为什么使用#if 0进行块注释?

时间:2010-09-02 19:40:46

标签: c compilation c-preprocessor

逆向工程代码,我对这种风格感到震惊,但我想确保没有充分理由做这些事情....

只是我还是这是一种可怕的编码风格

if ( pwbuf ) sprintf(username,"%s",pwbuf->pw_name);
else sprintf(username,"%d",user_id);

为什么在

中包装不用于编译的代码
#if 0
....
#endif

而不是评论?


编辑:正如下面解释的那样,这是由于我没有意识到flummox / * * /的可能性。

但我仍然不明白,为什么不使用你的编程环境工具或喜欢的文本编辑器的宏来阻止使用“//”将其注释掉

这不会更直接,更容易知道在视觉上跳过吗?


我是否对 C 缺乏经验,并且错过了为什么这些事情可能是一个好主意 - 或者没有任何借口,我有理由对这段代码的丑陋感到恼火? / p>

13 个答案:

答案 0 :(得分:36)

当删除的块包含块注释

时,会经常使用

#if 0

我不会说这是一个好习惯,但我经常看到它。

单行流控制+语句很容易理解,虽然我个人避免它(并且我已经禁止它的大多数编码指南)

顺便说一下,我可能会编辑标题有点用“为什么要使用#if 0代替块注释”

如果您有以下

#if 0
        silly();
        if(foo)
           bar();
        /* baz is a flumuxiation */
        baz = fib+3;
#endif

如果您天真地将#if 0 / #endif替换为/* */,则会导致注释在flumuxiation之后立即结束,当您点击*/时会导致语法错误代替上面的#endif ..

编辑:最后一点,通常在开发时使用#if 0语法,特别是如果您必须支持多个版本或依赖项或硬件平台。将代码修改为

并不罕见
#ifdef _COMPILED_WITHOUT_FEATURE_BAZ_
    much_code();
#endif

使用集中标头定义(或不​​定义)数百个#define常量。它不是世界上最漂亮的东西,但是每次我在一个体面的项目上工作时,我们都使用了运行时开关的一些组合,编译时常量(这个),编译时编译决策(只是使用不同的。 cpp取决于版本),以及偶尔的模板解决方案。这完全取决于细节。

虽然你是开发人员只是让事情起作用,但是......如果您不确定旧代码是否仍有价值,那么...... #if 0非常常见。

答案 1 :(得分:18)

评论是评论。他们描述了代码。

从编译中排除的代码是代码,而不是注释。它通常会包含注释,用于描述当前未编译的代码/

它们是两个截然不同的概念,强制使用相同的语法会让我觉得错误。

答案 2 :(得分:5)

除了C样式注释没有嵌套的问题之外,如果使用支持代码折叠的编辑器,则禁用#if 0的代码块可以折叠。在任何编辑器中也很容易做到,而在没有编辑器支持/宏的情况下,用C ++风格的注释禁用大块代码可能会很难实现。

此外,许多#if 0块也有else块。这提供了一种在两个实现/算法之间交换的简单方法,并且可以说比批量注释掉一个部分并且大量注释另一个部分更不容易出错。但是,在这种情况下,最好使用像#if DEBUG这样更具可读性的东西。

答案 3 :(得分:3)

那就是那个非常惯用的C。我不明白它有什么问题。它不是一段很漂亮的代码,但它很容易阅读,并且很清楚发生了什么,为什么,即使没有上下文。

变量名称可能更好,并且使用snprintfstrncpy可能更安全。

如果您认为它可能更好,您希望它看起来像什么?

我可能会稍作改动:

char username[32];
strncpy(username, 30, (pwbuf ? pwbuf->pw_name : user_id));
username[31] = '\0';

答案 4 :(得分:3)

就使用//进行块评论而言,我能想到的一个原因是,如果您将代码检入源控制系统,那么责备日志会将您显示为最后一个编辑器代码行。虽然您可能希望将评论归于您,但同时代码本身也归于您。当然,如果您需要检查代码的“真正”作者的责备日志,您可以返回并查看以前的修订版本,但如果在当前版本中保留该信息,则可以节省时间。

答案 5 :(得分:1)

显然,每个人对这类事情都有自己的看法。所以这是我的:

从不编写如上所述的代码,并且会更少考虑那些做过的人。我无法计算人们认为没有范围括号可以逃脱的次数,然后被它咬了。

将控制语句放在与代码块相同的行上更糟糕;缺乏缩进使得在阅读时更难看到流量控制。一旦你编写了几年,你就习惯了能够快速准确地阅读和解释代码,只要你能依赖某些视觉线索。为“特殊情况”规避这些线索意味着读者必须停下来做双重操作,这是没有充分理由的。

另一方面,

#if (0)在开发期间是可以的,但是一旦代码“稳定”(或者至少用一些有意义的预处理器符号名替换0)就应该删除。

答案 6 :(得分:0)

哇哦!不要反应过度......

我认为它的间隙比其他任何东西都要差。我有时间在哪里发现将短语与IF进行同一行更好,尽管这些陈述正在扩展它。

内联样式更适合垂直简洁......可以轻松分为4行,更多行

if (pwbuf) 
  sprintf(username,"%s",pwbuf->pw_name); 
else 
  sprintf(username,"%d",user_id); 

就个人而言,我讨厌下一个风格,因为它如此啰嗦,因此很难浏览文件。

if (pwbuf) 
{
  sprintf(username,"%s",pwbuf->pw_name); 
}
else
{ 
  sprintf(username,"%d",user_id); 
}

答案 7 :(得分:0)

以上指出。但监视器是宽屏的,而且现在,我有点不介意

if (pwbuf) sprintf(username,"%s",pwbuf->pw_name);
else       sprintf(username,"%d",user_id);

似乎总是有太多的水平空间,而且屏幕上没有足够的垂直空间!

此外,如果代码块已经有预处理程序指令,请不要使用#if 0;如果代码已经有块注释,请不要使用/* */。如果已经有两者,要么使用具有 ctrl + / 的编辑器来注释掉许多行。如果没有,你就塞满了,直接删除代码!

答案 8 :(得分:0)

if ( pwbuf ) sprintf(username,"%s",pwbuf->pw_name);
else sprintf(username,"%d",user_id);

惯用语和简洁。如果触摸超过2或3次,我会支架并下一行。如果添加日志记录信息或其他条件,则无法维护。

#if 0
....
#endif

很好打开调试代码块。此外,将避免与尝试阻止评论此类事情相关的编译错误:

/* line comment */
...
/* line comment again */

由于C块注释不嵌套。

答案 9 :(得分:0)

偶尔我会使用更简洁的样式,因为它支持代码的对称性,并且行不会太长。采取以下设计的例子:

if (strcmp(s, "foo") == 0)
{
    bitmap = 0x00000001UL;
    bit = 0;
}
else if (strcmp(s, "bar") == 0)
{
    bitmap = 0x00000002UL;
    bit = 1;
}
else if (strcmp(s, "baz") == 0)
{
    bitmap = 0x00000003UL;
    bit = 2;
}
else if (strcmp(s, "qux") == 0)
{
    bitmap = 0x00000008UL;
    bit = 3;
}
else
{
    bitmap = 0;
    bit = -1;
}

和简洁版本:

if      (strcmp(s, "foo") == 0) { bitmap = 0x00000001UL; bit = 0;  }
else if (strcmp(s, "bar") == 0) { bitmap = 0x00000002UL; bit = 1;  }
else if (strcmp(s, "baz") == 0) { bitmap = 0x00000003UL; bit = 2;  }
else if (strcmp(s, "qux") == 0) { bitmap = 0x00000008UL; bit = 3;  }
else                            { bitmap = 0;            bit = -1; }

虫子更容易直接跳到你的脸上。

免责声明:正如我所说,这个例子是人为的。随意讨论使用strcmp,幻数以及基于表格的方法会更好。 ;)

答案 10 :(得分:0)

#if是一个宏,用于检查写在它旁边的条件,因为“ 0”代表假,这意味着在“ #if 0”和“ #endif”之间编写的代码块将不被编译因此可以视为评论。

因此,我们基本上可以说#if 0用于在程序中编写注释。

示例:

#if 0
int a;
int b;
int c = a + b;
#endif

写在“ #if 0”和“ #endif”之间的部分被视为注释。

出现问题:“ / *…* /”可用于在程序中编写注释,然后为什么选择“ #if 0”?

答案:这是因为#if 0可以用于嵌套注释,但是“ / *…* /”不支持嵌套注释

什么是嵌套评论?嵌套注释表示注释下的注释,可以在各种情况下使用:

让我们举个例子,您编写了如下代码:

enter image description here

现在,有人正在查看您的代码,并想在您的程序中注释整个代码段,因为他不觉得需要这段代码。这样做的常见方法是:

enter image description here

上面是嵌套注释的示例。上面代码的问题是,一旦遇到“ / ”之后的第一个“ /”,注释就在那里结束。 即在上面的示例中,语句:int d = a-b;没有评论。

这可以通过使用“ if 0”来解决:

enter image description here

在这里,我们使用了#if 0嵌套的注释。

答案 11 :(得分:0)

我可以列举几个使用 #if 0 的原因:

  • 注释不嵌套,#if 指令可以嵌套;

  • 更方便:如果您想暂时启用禁用的代码块,使用 #if 0 您只需将 1 放在 0 中。使用 /* */ 您必须同时删除 /**/;

  • 你可以放一个有意义的宏来代替0,比如ENABLE_FEATURE_FOO;

  • 自动格式化工具将格式化 #if 块内的代码,但忽略注释掉的代码;

  • grep #if 比查找评论更容易;

  • 它与 VCS 配合得更好,因为您无需接触原始代码,只需在其周围添加几行即可。

答案 12 :(得分:-1)

#if 0 ... #endif在较旧的C代码中非常常见。原因是使用C样式注释/* .... */进行注释不起作用,因为注释不会嵌套。

即使它很常见,我也说它在现代代码中没有地位。人们在过去的日子里做到了这一点,因为他们的文本编辑器无法自动阻止评论大部分内容。更相关的是,它们没有像我们现在那样进行适当的源代码控制。在生产代码中留下注释或#ifdef'd没有任何借口。