gcc检查文件是否为main(#if __BASE_FILE__ == __FILE__)

时间:2011-01-02 13:23:10

标签: c gcc macros

在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错了吗?

作为未来客人的总结:

  • 您无法使用#if
  • 比较字符串
  • BASE_FILE 是正在编译的文件的名称(实际上就是我想要的)。
  • 执行此操作的最佳方法是在编译期间使用-D
  • 设置标志

5 个答案:

答案 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()函数的文件的名称。