当指向__FILE__的指针超出作用域后,它是否仍然有效?

5
如果我想将__FILE__传递给一个对象,我需要复制字符串还是只需将其指针存储为const char*
我猜我需要复制,因为我认为它一旦超出作用域就会被释放。 __FILE__的指针提供任何保证吗?

这是一个预处理器的事情 - 所以要复制一份。 - Ed Heal
3个回答

9

__FILE__ 扩展为普通字符串字面量。只要您仅仅是在读取它,您可以只使用像 const char* 这样的常量。

const char *filename = __FILE__;

由于字符串文字具有静态存储持续时间,因此指针将在整个程序中保持有效。如果您想要可修改的内容,则需要进行复制并自行管理其生命周期。有关预定义标准宏的完整列表以及有关它们扩展的信息,请查看此文档页面上的“预定义宏”部分。正如@Keith Thompson评论中正确指出的那样,不同的__FILE__扩展可能会产生相同或不同的地址。
const char *f1 = __FILE__;
const char *f2 = __FILE__;
assert(f1 == f2);              // May or may not fire

我不确定这会在什么时候影响到你,但知道这点还是好的。


1
请注意,如果您在代码的两个不同位置引用__FILE__,则两者都将引用包含相同字符串的静态数组对象(假设没有#line指令),但它们可能是具有不同地址的相同或不同的对象。 - Keith Thompson
这个答案实际上并不总是正确的。当一个动态加载的库被卸载时(例如使用dlopen/dlclose),所有指向它的__FILE__字面量的指针都将变得无效。 - Sander Mertens
@SanderMertens 好的,但是程序的“卸载”部分超出了标准和本答案的范围。它不是本问答关于“生命周期”概念的一部分。 - Baum mit Augen
@BaummitAugen同意,尽管遇到我描述的问题的人可能最终会来到这个页面,所以我认为捕捉它是很好的。 - Sander Mertens

3

__FILE__是一个预处理器宏,在预处理器运行时被替换为字符串字面量。任何使用它的地方就好像在源代码中输入了"filename.c"一样。它不是指针,也没有作用域,并且不会被释放 - 这些都是编译时和运行时的概念,不适用于它。


1
我猜需要复制,因为我认为一旦超出范围它就会自由释放。
不,这是一个字符字面值。它永远不会“超出范围”。
指向__FILE__的指针提供了任何保证吗?
是的。如上所述,它被推断为const char []字符字面值类型,这表明您不需要关心内存管理。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接