dat*_*olf 3 c c++ language-lawyer
一段继承代码中的重复模式是,只要其中一个函数返回某个值,就会调用函数链并中止该链。该值随后将用于后续计算。为了演示起见,破坏值为0。考虑以下程序:
#include <stdio.h>
static int n;
static int foo(int x)
{
fprintf(stderr, "%d(%d) ", x, n++);
return x ? 0 : n;
}
static void with_if(void)
{
int rc;
n = 0;
do {
if( (rc = foo(1)) ) break;
if( (rc = foo(2)) ) break;
if( (rc = foo(3)) ) break;
if( (rc = foo(4)) ) break;
if( (rc = foo(0)) ) break;
if( (rc = foo(5)) ) break;
} while(0);
fprintf(stderr, ">>%d<<\n", rc);
}
void with_short_circuit(void)
{
int rc;
n = 0;
(rc = foo(1))
|| (rc = foo(2))
|| (rc = foo(3))
|| (rc = foo(4))
|| (rc = foo(0))
|| (rc = foo(5));
fprintf(stderr, ">>%d<<\n", rc);
}
int main(int argc, char *argv[])
{
with_if();
with_short_circuit();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
请注意,短路变体不仅更简洁,而且(恕我直言)也更容易阅读和推理,因为在阅读该代码时,您不必将所有其他周围的语句推入您的思维堆栈中。所以我大体上更喜欢短路的变体。
就 GCC-4.9.3 和 Clang-3.6.2 而言with_if,with_short_circuit它们是相同的(它们产生完全相同的汇编输出)。
我担心的是,布尔运算符链的结果会被忽略(如果使用-WallGCC 编译会发出警告,但 Clang 仍然保持沉默)并且这可能被视为优化的机会。当然,调用 foo 会产生副作用,因此在我对 C 语言标准的理解中,使用布尔短路进行这样的控制流应该是安全的。有点我不太确定。
| 归档时间: |
|
| 查看次数: |
656 次 |
| 最近记录: |