このトピックをもう一度開いて申し訳ありませんが、このトピック自体について考えると、未定義動作が発生し始めました。明確に定義された動作のゾーンに移動したい。
与えられた
int i = 0;
int v[10];
i = ++i; //Expr1
i = i++; //Expr2
++ ++i; //Expr3
i = v[i++]; //Expr4
上記の表現を(この順序で)次のように考えます
operator=(i, operator++(i)) ; //Expr1 equivalent
operator=(i, operator++(i, 0)) ; //Expr2 equivalent
operator++(operator++(i)) ; //Expr3 equivalent
operator=(i, operator[](operator++(i, 0)); //Expr4 equivalent
ここでの動作については、 C++0xからの重要な引用です。
$ 1.9 / 12-「式(または部分式)の評価には、一般に、値の計算(左辺値評価のためのオブジェクトのIDの決定と、右辺値評価のためにオブジェクトに以前に割り当てられた値のフェッチを含む)と副作用の開始の両方が含まれます。 。」
$ 1.9 / 15-「スカラーオブジェクトの副作用が、同じスカラーオブジェクトの別の副作用、または同じスカラーオブジェクトの値を使用した値の計算に比べて順序付けされていない場合、動作は定義されていません。」
[注:異なる引数式に関連する値の計算と副作用は順序付けられていません。—エンドノート]
$ 3.9 / 9-「算術型(3.9.1)、列挙型、ポインター型、メンバー型へのポインター(3.9.2)、std :: nullptr_t、およびこれらの型のcv修飾バージョン(3.9.3)はまとめて呼び出されますスカラー型。」
Expr1では、式
i
(最初の引数)の評価は、式(副作用があります)の評価に関して順序付けられていませんoperator++(i)
。したがって、Expr1の動作は未定義です。
Expr2では、式
i
(最初の引数)の評価は、operator++(i, 0)
(副作用がある)式の評価に関して順序付けられていません。したがって、Expr2の動作は未定義です。
Expr3では、 outerが呼び出される
operator++(i)
前に、lone引数の評価を完了する必要があります。operator++
したがって、Expr3の動作は明確に定義されています。
Expr4では、式
i
(最初の引数)の評価は、operator[](operator++(i, 0)
(副作用があります)の評価に関して順序付けられていません。したがって、Expr4の動作は未定義です。
この理解は正しいですか?
PSOPのように式を分析する方法が正しくありません。これは、@ Potatoswatterのように、次のように述べているためです。「13.6節は適用されません。13.6/ 1の免責事項を参照してください。」これらの候補関数は、13.3.1.2で説明されている演算子のオーバーロード解決プロセスに参加し、他の目的には使用されません。 「これらは単なるダミーの宣言です。組み込み演算子に関しては、関数呼び出しのセマンティクスは存在しません。」