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