在ruby中,有一个非常常见的习惯用法来检查当前文件是否为“主”文件:
if __FILE__ == $0
# do something here (usually run unit tests)
end
在阅读gcc文档之后,我想在 C 中做类似的事情我认为它应该像这样工作:
#if __FILE__ == __BASE_FILE__
// Do stuff
#endif
唯一的问题是在我尝试之后:
$ gcc src/bitmap_index.c -std=c99 -lm && ./a.out
src/bitmap_index.c:173:1: error: token ""src/bitmap_index.c"" is not valid in preprocessor expressions
我使用#if错了吗?
作为未来客人的总结:
答案 0 :(得分:6)
在gcc中你可以使用:
#if __INCLUDE_LEVEL__ == 0
或:
如果(!__ INCLUDE_LEVEL __)
检查你的内部__BASE_FILE __
答案 1 :(得分:4)
是的,你在滥用#if
。它仅适用于整数常量表达式。但即使您使用if
,比较指针的相等也绝不是比较C中字符串的有效方法。
答案 2 :(得分:2)
看来你不能。
或者,它在常规if条件下完全正常,gcc可以很好地优化它。
if (!strcmp(__BASE_FILE__, __FILE__)) {
// works.
}
但您无法定义新的主要功能或使用其他预处理器技巧。但你可以通过使用静态方法来短路主,但那是苛刻和肮脏的。
但也许你不应该这样做。在Ruby / python中,这是有效的,因为文件的使用是在运行时完成的。在C中,所有文件都要编译使用。
请记住,大多数构建系统将一次构建一个文件,将它们构建为目标文件,并仅在必要时重建它们。所以
__BASE_FILE__ and __FILE__
如果不是总是,将在源文件中大部分时间等于。我强烈建议你不要在头文件中这样做。
将测试放在单独的文件中更容易,只在需要时才链接它们。
答案 3 :(得分:1)
是的,正如其他人所说,你是在滥用它,因为你无法在C语言中比较字符串,特别是在预处理器中没有。
定义int main(int argc, char* argv[])
的文件是主文件。可执行文件中只能有一个这样的函数。
答案 4 :(得分:1)
除了其他人所说的(你不能让C预处理器比较字符串),要小心__BASE_FILE__
,因为它可能与你对“main”文件的定义不一致。 __BASE_FILE__
是正在编译的文件的名称,因此它始终等于源文件中的__FILE__
,并且只在标题和其他包含的文件中有所不同。
特别是,__BASE_FILE__
不是包含main()
函数的文件的名称。