让我们将您的代码重写为
E1 = (E2 = E3)
其中 E1 是表达式a
,E2 是表达式a += 1
,E3 是表达式10
。在这里,我们使用了赋值运算符从右到左分组(C++11 标准中的第 5.17/1 节)。
§5.17/1 还指出:
在所有情况下,赋值都在左右操作数的值计算之后和赋值表达式的值计算之前进行排序。
将此应用于我们的表达式意味着我们首先必须评估子表达式E1
和E2 = E3
。请注意,这两个评估之间没有“sequenced-before”关系,但这不会导致任何问题。
id-expression 的评估E1
是微不足道的(结果就是a
它本身)。赋值表达式 的求值过程E2 = E3
如下:
首先必须评估两个子表达式。文字 的评估E3
又是微不足道的(给出值 10 的纯右值)。
(复合)赋值表达式 E2
的评估按以下步骤完成:
1) 的行为a += 1
等价于a = a + 1
但a
只评估一次 (§5.17/7)。在评估子表达式a
和1
(以任意顺序)之后,应用左值到右值的转换a
以读取存储在a
.
2) a
(which is 0
) 和 of的值1
被相加 ( a + 1
) 并且这个相加的结果是 value 的纯右值1
。
3) 在我们计算赋值结果之前a = a + 1
,左操作数所指的对象的值被右操作数的值替换(第 5.17/2 节)。的结果E2
是一个引用新值的左值1
。请注意,副作用(更新左操作数的值)在赋值表达式的值计算之前排序。这是上面引用的§5.17/1。
现在我们已经评估了子表达式E2
和E3
,表达式所E2
引用的值被替换为 的值E3
,即10
。因此 的结果E2 = E3
是 value 的左值10
。
最后,表达式E1
引用的值被替换为表达式的值E2 = E3
,我们计算为10
。因此,变量a
最终包含 value 10
。
由于所有这些步骤都是明确定义的,因此整个表达式会产生明确定义的值。