短路评估和副作用

Łuk*_*mek 18 c

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

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

int c = 0;
if (c && func(c)) { /* whatever... */ }
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

Ama*_*osh 24

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

是.因为有一个序列点

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


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


dir*_*tly 5

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