use*_*329 6 c comments conditional-compilation c-preprocessor
假设没有定义MACRO,这些是等价的
#ifdef MACRO
Not valid C or C++ code
#endif
/*
Not valid C or C++ code
*/
Run Code Online (Sandbox Code Playgroud)
在GCC 4.7.1中,它似乎是等效的,但是有更多的预处理器吗?
这取决于你的意思是"无效的C或C++代码".
注释中的文本不必符合该语言的大多数规则.它甚至没有被标记化.这完全有效:
/* This comment doesn't contain a valid sequence of preprocessing tokens
(because of the apostrophe). */
Run Code Online (Sandbox Code Playgroud)
它必须服从的唯一规则是控制评论结束的那些规则.人们经常会在行注释中反斜杠换行(注意SO的语法荧光笔会出错!)
// Line comment with ascii art ending with a \
Oops! This line is commented out too!
Run Code Online (Sandbox Code Playgroud)
并且不经常(如果只是因为每个C教程都警告你这个)通过块注释而不是嵌套(语法高亮显示器得到这个权利):
/* you can't nest /* block comments */ these words are not commented */
Run Code Online (Sandbox Code Playgroud)
在另一方面,在一个"跳过"预处理器条件"组"的文本也必须符合一定的语言规则.标准的确切词汇(C99§6.10.1p5)是
按顺序检查每个指令的条件.如果它的计算结果为false(零),则跳过它控制的组:仅通过确定指令的名称处理指令,以便跟踪嵌套条件的级别; 其他指令的预处理标记将被忽略,组中的其他预处理标记也将被忽略.
有两个重要的部分.首先,该文本被标记化,所以它也必须是预处理标记的有效序列.
#if 0
This skipped conditional group doesn't contain a valid sequence of
preprocessing tokens (because of the apostrophe).
#endif
Run Code Online (Sandbox Code Playgroud)
是语法错误.
$ gcc -fsyntax-only test.c
test.c:2:37: warning: missing terminating ' character
this skipped conditional group doesn't contain a valid sequence of
^
Run Code Online (Sandbox Code Playgroud)
其次,指令仍然部分处理"以便跟踪嵌套条件的级别",这意味着你可以这样做:
#if 0 // forget this entire mess
#ifdef __linux__
do_linux_specific_thing();
#elif defined __APPLE__
do_osx_specific_thing();
#elif defined _WIN32
do_windows_specific_thing();
#endif
#endif
Run Code Online (Sandbox Code Playgroud)
你不能做这个:
#ifdef __linux__
do_linux_specific_thing();
#elif defined __APPLE__
do_osx_specific_thing();
#if 0 // forget windows
#elif defined _WIN32
do_windows_specific_thing();
#endif
#endif
Run Code Online (Sandbox Code Playgroud)
(你最后不会得到错误,但......
$ gcc -E -P -U__linux__ -D__APPLE__ -D_WIN32 test.c
do_osx_specific_thing();
do_windows_specific_thing();
Run Code Online (Sandbox Code Playgroud)
......我不认为这是谁写它意味着它.)
该语言的许多指南告诉您使用#if 0"注释掉"要暂时禁用的大部分代码区域.他们这样说是因为块注释没有嵌套.如果您尝试使用块注释禁用代码区域,但该区域内存在块注释,则注释将过早结束,并且可能代码将无法编译.在C没有行评论的日子里,这一点更为重要; 一些项目仅使用行注释进行注释,为禁用代码保留块注释.
但是因为里面的代码#if 0...... #endif仍然记号化和嵌套预处理条件仍必须平衡,你必须要小心一点在哪里你把#if 0和#endif.它通常不是问题,因为在您禁用它之前用于编译的代码,因此它不应该有任何内容导致标记化错误.
在一般情况下,两者都是等价的.
但是,如果您的"无效C或C++代码"包含注释,则第一个表单将起作用,而第二个表单不起作用.那是因为C标准禁止叠加评论.
/* Comments /* inside */ comments are not allowed. */
Run Code Online (Sandbox Code Playgroud)
在这种情况下,BTW #if 0经常被推荐#ifdef MACRO.
#if 0
Invalid C source code
#endif
Run Code Online (Sandbox Code Playgroud)
看到这个问题.
是的,它们是等价的,预处理阶段将Not valid C or C++ code在编译器正确看到代码之前消除.
预处理涉及删除注释和已删除的代码#if.
但是,如果有人编译代码-DMACRO,#ifdef版本会让你遇到麻烦,最好#if 0通过预处理器删除代码.
| 归档时间: |
|
| 查看次数: |
9381 次 |
| 最近记录: |