考虑以下代码:
我们知道由于前缀++,i的修改总是在i的值计算之前发生。
然后根据规则:
表达式(或子表达式)的评估通常包括值计算(包括确定用于glvalue评估的对象的标识和获取先前分配给对象的值以进行prvalue评估)和副作用的启动
如果对内存位置的副作用与同一内存位置上的另一个副作用或使用同一内存位置中任何对象的值进行的值计算不确定顺序,并且它们不可能并发,则行为未定义。
无论是在 A 评估之前还是之后对 B 进行评估,与相应值计算或
并且
将个别运算符的操作数的评估视为A。将个别表达式的子表达式的评估视为B。A与B彼此之间是不按顺序进行的。
哪种解释是正确的?
int main(){
int i = 0;
int a = ++i + ++i;
}
我找不到任何说明+
操作数无顺序的信息。因此,根据标准,二进制+
操作数的顺序是不确定的。
该引用的意思是评估A可以在B之前发生,或者评估B可以在A之前发生。而无序评估的执行可以重叠,而不确定顺序的评估不能重叠,它们是不同的。对于任意两个评估 A 和 B,如果 A 在 B 之前排序(或者等价地,B 在 A 之后排序),则 A 的执行必须在 B 之前。如果 A 没有排序在 B 之前,并且 B 没有排序在 A 之前,则 A 和 B 是无序的。[注:未排序评估的执行可以重叠。—end note]
当 A 在 B 之前排序或 B 在 A 之前排序时,评估 A 和 B 是不确定排序的。[注:不确定排序的评估不能重叠,但可以先执行其中一个。—end note]
我们知道由于前缀++,i的修改总是在i的值计算之前发生。
然后根据规则:
表达式(或子表达式)的评估通常包括值计算(包括确定用于glvalue评估的对象的标识和获取先前分配给对象的值以进行prvalue评估)和副作用的启动
如果对内存位置的副作用与同一内存位置上的另一个副作用或使用同一内存位置中任何对象的值进行的值计算不确定顺序,并且它们不可能并发,则行为未定义。
无论是在 A 评估之前还是之后对 B 进行评估,与相应值计算或
++i + ++i;
的副作用无关的副作用不存在。因为不确定顺序的评估不能重叠,因此两个评估中的一个必须在另一个之前完全执行。评估包括值计算和副作用。因此,在另一个之前计算了一个增量到 i
。
然而,未排序的评估遵循不同的规则,因此如果二元 +
操作数的评估是未排序的而不是不确定顺序的,则混淆将得到解决。如果我在上面的分析中错过了标准中的某些内容,请纠正我。
更新
我发现以下句子,它似乎表明评估是无序的:
除非另有说明,否则单个运算符的操作数和单个表达式的子表达式的评估没有顺序。
然而,我不知道如何正确理解这个句子。我想到了两种解释:
对于运算符A,其操作数的评估彼此之间是不按顺序进行的;对于表达式B,其子表达式的评估彼此之间也是不按顺序进行的。并且
将个别运算符的操作数的评估视为A。将个别表达式的子表达式的评估视为B。A与B彼此之间是不按顺序进行的。
哪种解释是正确的?