在下列情况下,是否允许编译器优化对foo()
和\或整个if
块的调用?
if( foo() && 0 )
{ ... }
答案 0 :(得分:14)
从标准的角度来看,编译器必须评估左侧,即必须调用foo()
:
[C99,6.5.13] 与按位二进制
&
运算符不同,&&
运算符保证从左到右的评估; 在评估第一个操作数后有一个序列点。如果是第一个操作数 比较等于0,不评估第二个操作数。
但是因为它知道if
语句的主体永远无法到达, * 然后它可以省略该部分的任何相应代码。
当然,如果编译器可以证明foo()
没有可观察到的副作用,那么它也可以自由地优化该调用。但这与短路行为没什么关系。
<小时/> *(仅限C ++)假设
foo()
未返回重载为operator&&
的类型。
答案 1 :(得分:2)
在确定foo
表示0
中的语句未执行之前,编译器必须执行if
。但是,如果foo
是一个非常简单的函数,没有任何副作用(不会改变任何全局状态 - 并且在C和C ++标准中有很长的定义),那么它本身可以被优化远。通常只有在foo
是相同源代码的一部分时才会发生。
答案 2 :(得分:1)
等效代码:
int x = (int) foo();
if (x)
if (0)
{ ... }
对于任意foo,你能“优化掉”第一行吗? foo
可能类似于
int foo() {
printf("x");
return 0;
}