为什么使用 #if 0 来注释掉块?

发布于 2024-09-16 23:18:58 字数 516 浏览 6 评论 0原文

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

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

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

以及为什么包装代码不适合编译而

#if 0
....
#endif

不是评论?


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

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

这不是更直接、更容易知道视觉上跳过吗?


我是否只是在C方面缺乏经验,并且不明白为什么这些东西可能是一个好主意——或者没有任何借口,并且我有理由对这段代码的丑陋感到恼火?

Reverse engineering code and I'm kind of appalled at the style, but I wanted to make sure there's no good reason for doing these things....

Is it just me or is this a horrible coding style

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

And why wrap code not intended for compilation in an

#if 0
....
#endif

Instead of comments?


EDIT: So as some explained below, this is due to the possibility to flummox /* */ which I didn't realize.

But I still don't understand, why not just use your programming environment tools or favorite text editor's macro's to block comment it out using "//"

wouldn't this be MUCH more straightforward and easy to know to visually skip?


Am I just inexperienced in C and missing why these things might be a good idea -- or is there no excuse, and I'm justified in feeling irritated at how ugly this code is?

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

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

发布评论

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

评论(13

甜味拾荒者 2024-09-23 23:18:58

当删除的块包含块注释时,#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 很常见。

#if 0 is used pretty frequently when the removed block contains block-comments

I won't say it's a good practice, but I see it rather often.

The single line flow-control+statement is easy enough to understand, although I personally avoid it (and most of the coding guidelines I've worked under forbid it)

BTW, I'd probably edit the title to be somewhat useful "Why use #if 0 instead of block comments"

If you have the following

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

If you naively replace the #if 0/#endif with /* */, that will cause the comment to end right after flumuxiation, causing a syntax error when you hit the */ in the place of the #endif above..

EDIT: One final note, often the #if 0 syntax is just used while developing, particularly if you have to support multiple versions or dependencies or hardware platforms. It's not unusual for the code to be modified to

#ifdef _COMPILED_WITHOUT_FEATURE_BAZ_
    much_code();
#endif

With a centralized header defining (or not) hundreds of those #define constants. It's not the prettiest thing in the world, but every time I've worked on a decent sized project, we've used some combination of runtime switches, compile-time constants (this), compile-time compilation decisions (just use different .cpp's depending on the version), and the occasional template solution. It all depends on the details.

While you're the developer just getting the thing working in the first place, though... #if 0 is pretty common if you're not sure if the old code still has value.

快乐很简单 2024-09-23 23:18:58

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

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

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


我正在编辑此内容,因为我正在进行大规模重构,并且正在大量使用此模式。

作为此重构的一部分,我删除了一些广泛使用的类型,并用另一种类型替换它们。结果当然是什么也建不起来。

我真的很讨厌花几天时间解决一个又一个问题,希望当我完成后一切都会构建并且所有测试都会运行。

所以我的第一步是#ifdef-out所有无法编译的代码,然后[忽略]所有调用它的单元测试。完成此操作后,一切都构建完成,并且所有不可忽略的测试都通过了。

结果是很多函数看起来像这样:

public void MyFunction()
{
#if true
    throw new NotImplementedException("JT-123");
#else
    // all the existing code that won't compile
#endif
}

然后我忽略单元测试,一次一个,然后修复这些函数,一次一个。

在我创建合并请求之前,我需要花几天的时间来完成所有这些,并且所有这些 #if 都将消失,但我发现在此过程中它很有帮助。

Comments are comments. They describe the code.

Code that's being excluded from compilation is code, not comments. It will often include comments, that describe the code that isn't being compiled, for the moment.

They are two distinct concepts, and forcing the same syntax strikes me as being a mistake.


I'm editing this because I'm in the middle of a sizeable refactor and I'm making heavy use of this pattern.

As a part of this refactor, I'm removing some widely-used types, and replacing them with another. The result, of course, is that nothing will build.

And I really hate spending days fixing one issue after another in the hope that when I'm done everything will build and all the tests will run.

So my first step is to #ifdef-out all the code that won't compile, and then to [Ignore] all the unit tests that call it. With this done everything builds and all the non-ignored tests pass.

The result is a lot of functions that look like this:

public void MyFunction()
{
#if true
    throw new NotImplementedException("JT-123");
#else
    // all the existing code that won't compile
#endif
}

Then I unignore the unit tests, one at a time, and then fix the functions, one at a time.

It's going to take me a couple of days to worth through all of it, and all of these #if's will be gone, before I create the pull request to merge this, but I find it helpful, during the process.

咋地 2024-09-23 23:18:58

除了 C 风格注释不能嵌套的问题之外,使用 #if 0 禁用代码块还有一个优点:如果您使用的编辑器支持代码折叠,则可以折叠代码块。在任何编辑器中都可以很容易地做到这一点,而如果没有编辑器支持/宏,则使用 C++ 风格的注释禁用大块代码可能会很麻烦。

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

Besides the problem with C-style comments not nesting, disabling blocks of code with #if 0 has the advantage of being able to be collapsed if you are using an editor that supports code folding. It is also very easy to do in any editor, whereas disabling large blocks of code with C++-style comments can be unwieldy without editor support/macros.

Also, many #if 0 blocks have an else block as well. This gives an easy way to swap between two implementations/algorithms, and is arguably less error-prone than mass-commenting out one section and mass-uncommenting another. However, you'd be better off using something more readable like #if DEBUG in that event.

时常饿 2024-09-23 23:18:58

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

As far as block commenting using // is concerned, one reason that I can think of is that, should you check that code into your source control system, the blame log will show you as the last editor for those lines of code. While you probably want the commenting to be attributed to you, at the same time the code itself is also being attributed to you. Sure, you can go back and look at previous revisions if you need to check the blame log for the "real" author of the code, but it would save time if one preserved that information in the current revision.

煮茶煮酒煮时光 2024-09-23 23:18:58

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

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

如果您认为它可以更好,您希望它是什么样子?

我可能会做一些小小的改变:

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

That's pretty idiomatic C right there. I don't see what's so wrong with it. It's not a beautiful piece of code but it's easy to read and is clear what's going on and why, even without context.

The variable names could be better, and and it'd probably be safer to use snprintf or perhaps strncpy.

If you think it could be better, what would you prefer it look like?

I might make a slight change:

char username[32];
strncpy(username, 30, (pwbuf ? pwbuf->pw_name : user_id));
username[31] = '\0';
也只是曾经 2024-09-23 23:18:58

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

永远不会编写像上面这样的代码,并且不会想到任何这样做的人。我无法计算有多少次人们认为没有瞄准镜支架就可以逃脱,然后却被它咬了。

将控制语句与代码块放在同一行就更糟糕了;缺乏缩进使得阅读时更难看到流程控制。一旦您编码了几年,您就会习惯于能够快速准确地阅读和解释代码,只要您可以依赖某些视觉提示即可。为了“特殊情况”而规避这些提示意味着读者必须停下来再看一遍,没有任何理由。

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

Obviously, everyone has their own opinions on this sort of thing. So here's mine:

I would never write code like the above, and would think less of anyone who did. I can't count the number of times people think it's ok to get away without scope braces, and then been bitten by it.

Putting the control statement on the same line as the code block is even worse; the lack of indenting makes it harder to see the flow control whilst reading. Once you've been coding for a few years, you get used to being able to read and interpret code quickly and accurately, so long as you can rely on certain visual cues. Circumventing these cues for "special cases" means that the reader has to stop and do a double-take, for no good reason.

#if (0), on the other hand, is ok during development, but should be removed once code is "stable" (or at least replace 0 with some meaningful preprocessor symbol name).

你列表最软的妹 2024-09-23 23:18:58

哇哦!不要反应过度……

我会说它比其他任何东西都更草率,因为间距不一致。我曾经有一段时间发现最好将简短的语句与 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); 
}

Woah there! Don't overreact...

I would call it sloppier for more the inconsistant spacing than anything else. I have had time where I found it better to put short statements on the same line as their IF, though those statements are stretching it.

The inline style is better for vertical brevity... could easily be broken into 4, more lines

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

Personally I hate the next style since it so long-winded, making it difficult to skim a file.

if (pwbuf) 
{
  sprintf(username,"%s",pwbuf->pw_name); 
}
else
{ 
  sprintf(username,"%d",user_id); 
}
风渺 2024-09-23 23:18:58

上述几点。但现在显示器都是宽屏的,我有点不介意

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

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

另外,如果代码块已经有预处理器指令,请不要使用 #if 0;如果代码已经有块注释,请不要使用 /* */。如果两者都已存在,则可以使用具有 ctrl+/ 的编辑器来注释掉大量行。如果没有,你就吃饱了,直接删除代码!

points above noted. But monitors being widescreen and all, these days, I sort of don't mind

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

Always seem to have too much horizontal space, and not enough vertical space on my screen!

Also, if the code block already has preprocessor directives, don't use #if 0; if the code already has block comments, don't use /* */. If it already has both, either resort to an editor that has a ctrl+/, to comment out lots of lines. If not, you're stuffed, delete the code outright!

灯角 2024-09-23 23:18:58
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 块注释不嵌套。

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

Idiomatic and concise. If it got touched more than 2 or 3 times, I would bracket and next-line it. It's not very maintainable if you add logging information or other conditions.

#if 0
....
#endif

Good to turn on blocks of debug code or not. Also, would avoid compilation errors related to trying to block comment this sort of thing out:

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

Since C block comments don't nest.

情栀口红 2024-09-23 23:18:58

当它支持代码的对称性并且行不会变得太长时,我偶尔会使用更简洁的样式。采取以下人为的示例:

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、幻数的使用以及基于表的方法是否会更好。 ;)

Very occasionally I use the more concise style when it supports the symmetry of code and the lines don't get too long. Take the following contrived example:

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;
}

and the concise version:

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; }

Bugs are much more likely to jump straight into your face.

Disclaimer: This example is contrived, as I said. Feel free to discuss the use of strcmp, magic numbers and if a table based approach would be better. ;)

静谧幽蓝 2024-09-23 23:18:58

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

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

示例:

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

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

问题来了:“/* … */”可以用来在程序中写注释,那为什么要使用“#if 0”呢?

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

什么是嵌套注释?嵌套注释意味着注释下的注释,可以在各种情况下使用,例如:

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

在此处输入图像描述

现在,有人正在审查您的代码并想要对整个代码进行评论你的程序中的一段代码,因为,他觉得不需要这段代码。常见的方法是:

在此处输入图像描述

上面是嵌套注释的示例。上面代码的问题是,只要“//”遇到 em>” 时,注释就结束了。
即,在上面的例子中,语句:int d = ab;不予评论。

这是通过使用“if 0”解决的:

在此处输入图像描述

此处,我们使用 #if 0 使用嵌套注释。

#if is a macro which checks for the condition written aside to it, since ‘0’ represents a false, it means that the block of code written in between ‘#if 0’ and ‘#endif’ will not be compiled and hence can be treated as comments.

So, we can basically say that #if 0 is used to write comments in a program.

Example :

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

The section written between “#if 0” and “#endif” are considered as comments.

Questions arises : “/* … */” can be used to write comments in a program then why ”#if 0”?

Answer : It is because, #if 0 can be used for nested comments but nested comments are not supported by “/* … */”

What are nested comments? Nested Comments mean comments under comments and can be used in various cases like :

Let us take an example that you have written a code like below:

enter image description here

Now, someone is reviewing your code and wants to comment this whole piece of code in your program because, he doesn’t feel the need for this piece of code. A common approach to do that will be :

enter image description here

The above is an example of nested comments.The problem with the above code is, as soon as the first “/” after “/” is encountered, the comment ends there.
i.e., in the above example, the statement : int d = a-b; is not commented.

This is solved by using “if 0” :

enter image description here

Here, we have used nested comments using #if 0.

攒一口袋星星 2024-09-23 23:18:58

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

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

  • 更方便:如果您想暂时启用禁用的代码块,使用#if 0您只需输入1而不是0。对于 /* */,您必须删除 /**/;

  • 您可以放置​​一个有意义的宏来代替 0,例如 ENABLE_FEATURE_FOO

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

  • grep 查找 #if 比查找注释更容易;

  • 它与 VCS 配合使用效果更好,因为您无需触及原始代码,只需在其周围添加行即可。

I can name a few reasons for using #if 0:

  • comments don't nest, #if direcitves do;

  • It is more convenient: If you want to temporarily enable a disabled block of code, with #if 0 you just have to put 1 instead of 0. With /* */ you have to remove both /* and */;

  • you can put a meaningful macro instead of 0, like ENABLE_FEATURE_FOO;

  • automated formatting tools will format code inside #if block, but ignore commented out code;

  • it is easier to grep for #if than look for comments;

  • it plays nicer with VCS because you aren't touching the original code, just adding lines around it.

匿名的好友 2024-09-23 23:18:58

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

尽管它很常见,但我想说它在现代代码中没有地位。人们过去这样做是因为他们的文本编辑器无法自动阻止评论大段。更相关的是,他们没有像我们现在那样拥有适当的源代码控制。没有理由在生产代码中留下注释或#ifdef。

#if 0 ... #endif is pretty common in older C code. The reason is that commenting with C style comments /* .... */ doesn't work because comments don't nest.

Even though it is common, I'd say it has no place in modern code. People did it in olden days because their text editors couldn't block comment large sections automatically. More relevantly, they didn't have proper source code control as we do now. There's no excuse for leaving commented or #ifdef'd in production code.

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