短路评估和副作用

时间:2010-09-03 12:31:44

标签: c

好吧,我有点尴尬地问这个问题,但我只是想确定......

众所周知,C在布尔表达式中使用短路评估:

int c = 0;
if (c && func(c)) { /* whatever... */ }

在该示例中,func(c)未被调用,因为c评估为0。但是,比较的副作用会改变下一个被比较的变量的更复杂的例子呢?像这样:

int c; /* this is not even initialized... */
if (canInitWithSomeValue(&c) && c == SOMETHING) { /*...*/ }

函数canInitWithSomeValue返回true,并在成功时更改给定指针的值。是否保证后续比较(此示例中为c == SOMETHING)使用canInitWithSomeValue(&c)设置的值?

无论编译器使用多么繁重的优化?

3 个答案:

答案 0 :(得分:24)

  

是否保证后续比较(本例中为c == SOMETHING)使用canInitWithSomeValue(& c)设置的值?

是。因为有sequence point

  

在评估&&(逻辑AND),||(逻辑OR)和逗号运算符的左右操作数之间。例如,在表达式*p++ != 0 && *q++ != 0中,在尝试访问q之前,子表达式* p ++!= 0的所有副作用都已完成。


  

序列点定义计算机程序执行中的任何一点,保证先前评估的所有副作用都已执行,并且尚未执行后续评估的副作用。

答案 1 :(得分:5)

是。因为&&||运算符都称为序列点。后者定义何时完成前一操作的副作用,而下一操作的副作用不应该开始。

答案 2 :(得分:1)

if语句复合条件内的评估严格从左到右。 if中的第二个测试将被优化的唯一情况是编译器是否可以100%确定第一个测试是否完全等于false。