在 C / C ++
中 #if 0
/ #endif
块之间的代码会发生什么变化?
#if 0
//Code goes here
#endif
代码是否被简单地跳过,因此不会被执行?
答案 0 :(得分:126)
它不仅没有被执行,甚至没有被编译。
#if
是一个预处理器命令,在实际编译步骤之前进行评估。该块中的代码不会出现在已编译的二进制文件中。
它通常用于暂时删除代码段,以便以后再打开它们。
答案 1 :(得分:65)
除了一个重要的区别外,它与注释掉块是完全相同的:嵌套不是问题。请考虑以下代码:
foo();
bar(x, y); /* x must not be NULL */
baz();
如果我想发表评论,我可能会尝试:
/*
foo();
bar(x, y); /* x must not be NULL */
baz();
*/
Bzzt。语法错误!为什么?因为块注释不会嵌套,所以(正如您从SO的语法突出显示中看到的那样){NULL}后面的*/
终止注释,使baz
调用没有注释掉,{在*/
语法错误之后{1}}。另一方面:
baz
努力评论整个事情。并且#if 0
foo();
bar(x, y); /* x must not be NULL */
baz();
#endif
将彼此嵌套,如下所示:
#if 0
虽然如果没有正确评论,这当然会让人感到困惑并成为一种维护问题。
答案 2 :(得分:17)
它会永久注释掉该代码,因此编译器永远不会编译它。
编码员可以稍后更改#ifdef,以便在程序中编译该代码。
这就像代码不存在一样。
答案 3 :(得分:13)
#if 0 ... #endif块到底有什么作用?
它告诉你,作者显然从未听说过版本控制系统。反过来,这会告诉你尽可能远离......
答案 4 :(得分:12)
我想补充#else
案例:
#if 0
/* Code here will NOT be complied. */
#else
/* Code will be compiled. */
#endif
#if 1
/* Code will be complied. */
#else
/* Code will NOT be compiled. */
#endif
答案 5 :(得分:6)
当预处理器看到#if时,它会检查下一个标记是否具有非零值。如果是这样,它会保留编译器的代码。如果没有,它将摆脱该代码,因此编译器永远不会看到它。
如果有人说#if 0他们正在有效地评论代码,那么它将永远不会被编译。你可以把它想象成就像放在它周围的/ * ... * /一样。它不完全相同,但效果相同。
如果你想了解详细情况,你可以经常看。许多编译器将允许您在预处理器运行后查看文件。例如,在Visual C ++上,switch / P命令将执行预处理器并将结果放在.i文件中。
答案 6 :(得分:3)
以#
开头的行是preprocessor directives。 #if 0 [...] #endif
块不会进入编译器,也不会生成任何机器代码。
您可以使用源文件ifdef.cxx
来演示预处理器会发生什么:
#if 0
This code will not be compiled
#else
int i = 0;
#endif
运行gcc -E ifdef.cxx
将显示编译的内容。
您可以选择使用此机制来防止在开发周期中编译代码块,但您可能不希望将其检入源代码控制,因为它只会增加代码并降低可读性。如果它是已被注释掉的历史代码片段,那么它应该被删除:源代码控制包含历史记录,对吗?
此外,对于 C 和 C ++ ,答案可能相同,但没有一种称为C / C ++的语言,并且引用这样的语言不是一个好习惯语言。
答案 7 :(得分:1)
不完全
int main(void)
{
#if 0
the apostrophe ' causes a warning
#endif
return 0;
}
显示“t.c:4:19:警告:缺少终止'字符” 与gcc 4.2.4
答案 8 :(得分:1)
这是一种便宜的评论方式,但我怀疑它可能具有调试潜力。例如,假设您有一个将值输出到文件的构建。您可能不希望在最终版本中使用#if 0 ... #endif。
另外,我怀疑为调试目的而做的更好的方法是:
#ifdef DEBUG
// output to file
#endif
你可以做类似的事情,它可能更有意义,你所要做的就是定义DEBUG以查看结果。