コードを次のように書き直しましょう。
E1 = (E2 = E3)
ここで、E1 は式a
、E2 は式a += 1
、E3 は式10
です。ここでは、代入演算子が右から左にグループ化されることを使用しました (C++11 標準の§5.17/1)。
§5.17/1 はさらに次のように述べています。
いずれの場合も、代入は、右オペランドと左オペランドの値の計算の後、代入式の値の計算の前に順序付けされます。
これを式に適用すると、最初に部分式E1
and を評価する必要がありE2 = E3
ます。これらの 2 つの評価の間には "sequenced-before" 関係はありませんが、問題は発生しないことに注意してください。
id-expression の評価E1
は自明です (結果はa
それ自体です)。代入式 の評価は次のE2 = E3
ように進行します。
まず、両方の部分式を評価する必要があります。リテラル の評価もE3
自明です (値 10 の prvalue を与えます)。
(複合)割り当て式 E2
の評価は、次の手順で行われます。
1) の動作a += 1
は同等ですがa = a + 1
、a
一度しか評価されません (§5.17/7)。部分式a
and を1
(任意の順序で)評価した後、に格納されている値を読み取るために、左辺値から右辺値への変換が に適用されます。a
a
2) の値a
(これは0
) との値1
が加算され ( a + 1
)、この加算の結果は value の prvalue です1
。
3) 割り当ての結果を計算する前にa = a + 1
、左側のオペランドが参照するオブジェクトの値が右側のオペランドの値に置き換えられます (§5.17/2)。の結果はE2
、新しい値を参照する左辺値1
です。副作用 (左側のオペランドの値の更新) は、代入式の値計算の前に並べられることに注意してください。これは上記の§5.17/1 です。
部分式E2
とを評価したのでE3
、式が参照する値は の値でE2
置き換えられます。したがって、 の結果はvalue の左辺値です。E3
10
E2 = E3
10
最後に、式E1
が参照する値は式の値に置き換えられ、式E2 = E3
は と計算されます10
。したがって、変数a
には値が含まれることになります10
。
これらのステップはすべて明確に定義されているため、式全体から明確に定義された値が得られます。