2

在以下情况下,是否允许编译器优化对foo()和/或整个if块的调用?

if( foo() && 0 )
    { ... }
4

3 回答 3

14

从标准的角度来看,编译器必须评估左侧,即foo()必须调用:

[C99, 6.5.13]与按位二元&运算符不同,运算&&符保证从左到右的求值;在对第一个操作数求值之后有一个序列点。如果第一个操作数比较等于 0,则不计算第二个操作数。

但是因为它知道if语句的主体永远无法到达,*那么它可以自由地省略该部分的任何相应代码。

当然,如果编译器可以证明它foo()没有可观察到的副作用,那么也可以自由地优化该调用。但这与短路行为无关。


*(仅限 C++)假设foo()不返回重载为operator&&.

于 2013-06-25T07:35:28.763 回答
2

编译器必须foo在确定这0意味着未执行中的语句之前if执行。但是,如果foo是一个非常简单且没有副作用的函数(不会改变任何全局状态 - 在 C 和 C++ 标准中有很长的定义),那么它本身可以被优化掉。foo通常,只有在相同源代码的一部分时才会发生这种情况。

于 2013-06-25T07:40:41.250 回答
1

等效代码:

int x = (int) foo();
if (x)
    if  (0)
        { ... }

对于任意 foo,您可以“优化”第一行吗?foo可能是这样的

int foo() {
    printf("x");
    return 0;
}
于 2013-06-25T07:36:54.723 回答