短路评估和副作用
好,我有点尴尬地问这个问题,但我只是想确定…
已知C在布尔expression式中使用短路评估:
int c = 0; if (c && func(c)) { /* whatever... */ }
在这个例子中, func(c)
没有被调用,因为c
值为0
。 但是,比较副作用会改变下一个比较variables的更复杂的例子呢? 喜欢这个:
int c; /* this is not even initialized... */ if (canInitWithSomeValue(&c) && c == SOMETHING) { /*...*/ }
函数canInitWithSomeValue
返回true,并在成功的情况下改变给定指针的值。 是否保证后续比较(本例中为c == SOMETHING
)使用canInitWithSomeValue(&c)
设置的值?
无论编译器使用多么繁重的优化?
是否保证后续比较(本例中为c == SOMETHING)使用canInitWithSomeValue(&c)设置的值?
是。 因为有一个序列点
在
&&
(逻辑AND)的左和右操作数的评估之间,||
(逻辑OR)和逗号运算符。 例如,在expression式*p++ != 0 && *q++ != 0
,子expression式* p ++!= 0的所有副作用在任何尝试访问q之前完成。
顺序点定义了计算机程序执行过程中的任何点,在这个点上保证先前评估的所有副作用将被执行,并且没有来自后续评估的副作用尚未被执行。
是。 因为&&
和||
算子也叫做序列点。 后者定义了前一次手术的副作用何时应该完成,下一次手术的副作用是否应该开始。
在if语句复合条件内的评估严格地从左到右。 如果编译器能够以100%的确定性确定第一个等于false,那么在if中进行第二个testing的唯一情况就是优化。