C++11 標準 (ご存じのように、シーケンス ポイントの概念がなくなりました) のコンテキストで言えば、2 つの最も単純な例がどのように定義されているかを理解したいと思います。
int i = 0;
i = i++; // #0
i = ++i; // #1
SO には、C++11 コンテキスト内でこれらの例を説明する 2 つのトピックがあります。ここでは、#0
UB を呼び出して#1
明確に定義されていると述べました。ここでは、両方の例が未定義であると言われました。この曖昧さは私を大いに混乱させます。私はこのよく構成されたリファレンスをすでに 3 回読んだことがありますが、このトピックは私には複雑すぎるようです。
.
例を分析してみましょう#0
: i = i++;
.
対応する引用は次のとおりです。
組み込みのポストインクリメントおよびポストデクリメント演算子の値の計算は、その副作用の前に順序付けされます。
組み込み代入演算子とすべての組み込み複合代入演算子の副作用 (左引数の変更) は、左右両方の引数の値計算 (ただし副作用ではない) の後に並べられ、前に並べられます。代入式の値の計算 (つまり、変更されたオブジェクトへの参照を返す前)
スカラー オブジェクトに対する副作用が、同じスカラー オブジェクトに対する別の副作用と比較して順序付けられていない場合、動作は未定義です。
私が理解しているように、代入演算子の副作用は、その左と右の引数の副作用で順序付けられていません。したがって、代入演算子の副作用は、 の副作用と順序付けられませんi++
。したがって#0
、UB を呼び出します。
.
例を分析してみましょう#1
: i = ++i;
.
対応する引用は次のとおりです。
組み込みのプリインクリメントおよびプリデクリメント演算子の副作用は、その値の計算の前に順序付けられます (複合代入としての定義による暗黙のルール)。
組み込み代入演算子とすべての組み込み複合代入演算子の副作用 (左引数の変更) は、左右両方の引数の値計算 (ただし副作用ではない) の後に並べられ、前に並べられます。代入式の値の計算 (つまり、変更されたオブジェクトへの参照を返す前)
スカラー オブジェクトに対する副作用が、同じスカラー オブジェクトに対する別の副作用と比較して順序付けられていない場合、動作は未定義です。
この例が とどう違うのかわかりません#0
。とまったく同じ理由で、これは私にとってUBのようです#0
。代入の副作用は、 の副作用と順序付けられていません++i
。どうやらUBらしい。上記のトピックは、明確に定義されていると述べています。なんで?
.
質問: 例の UB を決定するために、引用されたルールを適用するにはどうすればよいですか? できるだけ簡単な説明をいただければ幸いです。ありがとうございました!