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

发布于 2024-10-09 20:40:21 字数 655 浏览 1 评论 0原文

在 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 设置标志

In ruby there's very common idiom to check if current file is "main" file:

  if __FILE__ == $0
    # do something here (usually run unit tests)
  end

I'd like to do something similar in C after reading gcc documentation I've figured that it should work like this:

  #if __FILE__ == __BASE_FILE__
    // Do stuff
  #endif

the only problem is after I try this:

$ 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

Am I using #if wrong?

As summary for future guests:

  • You cannot compare string using #if
  • BASE_FILE is the name of file that is being compiled (that Is actually what I wanted).
  • Best way to do this is to set flag during compilation with -D

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

爱*していゐ 2024-10-16 20:40:21

在 gcc 中,您可以使用:

#if __INCLUDE_LEVEL__ == 0

或:

if(!__INCLUDE_LEVEL__)

来检查您是否在 __BASE_FILE__ 内

in gcc you can use:

#if __INCLUDE_LEVEL__ == 0

or:

if(!__INCLUDE_LEVEL__)

to check if your inside the __BASE_FILE__

梦里人 2024-10-16 20:40:21

是的,您误用了#if。它仅适用于整数常量表达式。但即使您使用 if,比较指针是否相等也绝不是在 C 中比较字符串的有效方法。

Yes, you are misusing #if. It only works on integer constant expressions. But even if you were using if, comparing pointers for equality is never a valid way to compare strings in C.

内心旳酸楚 2024-10-16 20:40:21

看来你不能。

或者,它在常规 if 条件下工作得很好,并且 gcc 可以很好地优化它。

if (!strcmp(__BASE_FILE__, __FILE__)) {
    // works.
}

但您不能定义新的主函数或使用其他预处理器技巧。但是你可以使用静态方法来短路 main ,但这既严酷又肮脏。

但也许你不应该这样做。在 Ruby/python 中,这是可行的,因为文件的使用是在运行时完成的。在C语言中,所有文件都必须编译才能使用。

请记住,大多数构建系统一次构建一个文件,将它们构建为目标文件,并仅在必要时重建它们。所以

 __BASE_FILE__ and __FILE__

在源文件中大多数时候都会等于(如果不是总是)。我强烈建议您不要在头文件中执行此操作。

将测试放在单独的文件中,仅在需要时链接它们会更容易。

It seems you can't.

Alternatively, it works perfectly fine on a regular if condition, and gcc can optimize this nicely.

if (!strcmp(__BASE_FILE__, __FILE__)) {
    // works.
}

but you can't define new main functions or use other preprocessor tricks. but you could short-circuit main by using static methods, but that's harsh and dirty.

But maybe you shouldn't do it. in Ruby/python, this works because usage of files is done at runtime. in C, all files are to be compiled to be used.

Keep in mind that most build system will build one file at a time, building them as object files, and rebuilding them only when necessary. So

 __BASE_FILE__ and __FILE__

will be equals most of the time in sources files, if not always. And i would strongly discourage you to do this in header files.

It's easier to just put your tests in separate files, only linking them when needed.

陌上芳菲 2024-10-16 20:40:21

是的,正如其他人所说,您滥用了它,因为您无法在 C 中以这种方式比较字符串,尤其是在预处理器中。

定义 int main(int argc, char* argv[]) 的文件是主文件。可执行文件中只能有一个这样的函数。

Yup, as others say, you're misusing it since you can't compare strings that way in C, and especially not in the preprocessor.

The file that defines int main(int argc, char* argv[]) is the main file. There can be only one such function in an executable.

若水般的淡然安静女子 2024-10-16 20:40:21

除了其他人所说的(你不能让 C 预处理器比较字符串)之外,请小心 __BASE_FILE__ 因为它可能与你对“主”文件的定义不对应。 __BASE_FILE__ 是正在编译的文件的名称,因此它始终等于源文件中的 __FILE__,仅在头文件和其他包含的文件中有所不同。

特别是,__BASE_FILE__ 不是包含 main() 函数的文件的名称。

In addition to what others have said (you can't have the C preprocessor compare strings), be careful with __BASE_FILE__ because it may not correspond to your definition of "main" file. __BASE_FILE__ is the name of the file being compiled, so it's always equal to __FILE__ in source files, and only differs in headers and other included files.

In particular, __BASE_FILE__ is not the name of the file which contains the main() function.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文