Zza*_*nka 140 c if-statement
我的问题是关于我在主题中提到的那条线,我可以在生产代码中的许多地方看到.
整体代码如下所示:
if (0) {
// Empty braces
} else if (some_fn_call()) {
// actual code
} else if (some_other_fn_call()) {
// another actual code
...
} else {
// default case
}
Run Code Online (Sandbox Code Playgroud)
其他分支与我的问题无关.我想知道放在if (0)
这里的含义是什么.大括号是空的,所以我认为它不应该评论一些代码块.它会强制编译器进行一些优化还是意图不同?
我试图在SO和互联网上搜索这个明确的案例,但没有成功.关于JavaScript有类似的问题,但不是C.还有另一个问题,当在`if`条件中分配零时会发生什么?,但它讨论了对变量的零赋值,而不是'if(0)'用法本身.
CSM*_*CSM 104
如果有#if
语句,则这可能很有用
if (0)
{
// Empty block
}
#if TEST1_ENABLED
else if (test1())
{
action1();
}
#endif
#if TEST2_ENABLED
else if (test2())
{
action2();
}
#endif
Run Code Online (Sandbox Code Playgroud)
等等
在这种情况下,任何(和所有)测试都可以被#if
删除,代码将正确编译.几乎所有编译器都会删除该if (0) {}
部件.一个简单的自动生成器可以生成这样的代码,因为它稍微容易编码 - 它不必单独考虑第一个启用的块.
PSk*_*cik 90
我有时使用它来对称,所以我可以else if{
用编辑器自由地移动另一个,而不必考虑第一个if
.
语义上的
if (0) {
// Empty braces
} else
Run Code Online (Sandbox Code Playgroud)
part没有做任何事情,你可以指望优化器删除它.
Set*_*ers 44
我见过在生成代码中使用的类似模式.例如,在SQL中,我看到库发出以下where
子句.
where 1 = 1
Run Code Online (Sandbox Code Playgroud)
这可能会更容易添加其他标准,因为可以添加所有其他标准,and
而不是额外检查,看它是否是第一个标准.
Rus*_*ove 43
如上所述,该if (0) {}
条款汇编为零.
我怀疑这个梯子顶部的子句的功能是提供一个简单的位置来暂时禁用所有其他功能(用于调试或比较目的),通过更改0
为a 1
或true
.
小智 15
这是代码腐烂.
在某些时候,"if"做了一些有用的事情,情况发生了变化,也许正在评估的变量被删除了.
修复/更改系统的人尽可能少地影响系统的逻辑,因此他只是确保代码重新编译.所以他留下了"if(0)",因为这很快捷,而且他并不完全确定这是他想要做的.他让系统正常工作,他不会完全修复它.
然后下一个开发人员出现并且认为这是故意完成的,并且只注释掉那部分代码(因为它还没有被评估),然后在下次触摸代码时,这些注释被删除.
stu*_*dog 15
尚未提及的一种可能性:该if (0) {
线可能为断点提供方便的位置.
调试通常在非优化代码上完成,因此将出现始终为false的测试,并且能够在其上设置断点.编译生产时,代码行将被优化.看似无用的产品线为开发和测试构建提供了功能,而不会影响发布版本.
上面还有其他好的建议; 真正了解目的的唯一方法是追踪作者并提出要求.您的源代码控制系统可能会有所帮助.(寻找blame
类型功能.)
我已经在使用模板语言生成的预扩展JavaScript中看到了无法访问的代码块.
例如,您正在阅读的代码可能是从服务器粘贴的,该服务器预先评估了当时依赖于仅在服务器端可用的变量的第一个条件.
if ( ${requestIsNotHttps} ){ ... }else if( ...
Run Code Online (Sandbox Code Playgroud)
曾经编译过的:
if ( 0 ){ ... }else if ( ...
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助你重新激活专业回收编码器时代潜在的低键盘活动,我表现出热情!
该结构也可以在C中用于实现类型安全的通用编程,依赖于编译器仍然检查无法访问的代码这一事实:
// this is a generic unsafe function, that will call fun(arg) at a later time
void defer(void *fun, void *arg);
// this is a macro that makes it safer, by checking the argument
// matches the function signature
#define DEFER(f, arg) \
if(0) f(arg); \ // never actually called, but compile-time checked
else defer(f, (void *)arg); // do the unsafe call after safety check
void myfunction(int *p);
DEFER(myfunction, 42); // compile error
int *b;
DEFER(myfunction, b); // compiles OK
Run Code Online (Sandbox Code Playgroud)
我认为这只是糟糕的代码.在Compiler Explorer中编写一个快速示例,我们看到在gcc和clang中都没有为if (0)
块生成代码,即使完全禁用了优化:
为解决if (0)
生成的代码而去除原因并没有改变,因此我得出结论,这不是优化.
可能以前在顶部if
块中存在某些东西,后来被删除了.简而言之,看起来删除它会导致生成完全相同的代码,因此请随意执行此操作.
如上所述,零被评估为假,并且分支可能会被编译器优化掉.
我之前在代码中也看到了这个,其中添加了一个新功能并且需要一个kill-switch(如果该功能出现问题就可以将其关闭),并且一段时间后,当kill-switch被删除时程序员也没有删除分支,例如
if (feature_a_active()) {
use_feature_a();
} else if (some_fn()) {
...
Run Code Online (Sandbox Code Playgroud)
成为
if (0) {
// empty
} else if (some_fn()) {
...
Run Code Online (Sandbox Code Playgroud)