#if 0 ..... #endif块到底是做什么用的?

时间:2010-05-17 21:23:04

标签: c-preprocessor

C / C ++

#if 0 / #endif块之间的代码会发生什么变化?

#if 0

//Code goes here

#endif

代码是否被简单地跳过,因此不会被执行?

9 个答案:

答案 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以查看结果。