評価順
![]() |
このページは、Google 翻訳を使って英語版から機械翻訳されました。
翻訳には誤りや奇妙な言い回しがあるかもしれません。文章の上にポインタをおくと、元の文章が見れます。誤りを修正して翻訳を改善する手助けをしてください。翻訳についての説明は、ここをクリックしてください。 |
C++のあらゆる演算子のオペランド、関数呼出しの引数、また式の中の入れ子になった式の評価順は、以下に示したルールに該当する場合を除き、いかなる場合も定義されません。コンパイラはあらゆる順番で式を評価でき、また同じ式が別の場所で再度評価される場合においても別の順番で評価することが許されます。
C++では、「左から右」「右から左」といった評価順の概念はありません。例えばa + b + c
の c
は最初に評価される可能性もありますし、最後もしくは a
や b
と同時に評価される可能性もあります。
目次 |
[編集] Sequenced-before規則(C++11およびそれ以降)
[編集] 定義
[編集] 評価
各式、及び式の一部に対してコンパイラが行う評価は次の2種類となります:
- 値の計算: 式によって求まる値の計算。これにはオブジェクトのアイデンティティの決定が伴う場合(glvalueの評価。式がオブジェクトへの参照を返す場合)と以前オブジェクトに代入された値を読む場合(prvalueの評価。式が数値やその他の値を返す場合)があります。
- 副作用: volatile glvalueで示されるオブジェクトの読み書き、その他のオブジェクトへの書き込み、ライブラリI/O関数の呼出し、あるいは上に示した操作のいずれかを行う関数の呼出しによって生じます。
[編集] 評価順
評価順は、「AがBに先行する(sequenced-before)」という、非対称で推移的な二項関係によって式の各評価の間で単一のスレッドの範囲内で順序付けされます(アトミック型が評価の対象となる場合、std::memory_orderによってこの関係がスレッドを超えて定義される場合があります)。
- 「AがBに先行する」とき、Aの評価はBの評価が開始する前に完了します。
- 「AがBに先行しない」が「BがAに先行する」とき、Bの評価はAの評価が開始する前に完了します。
- 「AがBに先行しない」が「BがAに先行しない」とき、2つの可能性が生じます
- AとBの評価が順序付けされない場合。この場合、AとBの評価はいかなる順序でも評価される可能性があります。AとBの評価が同時に行われる可能性も存在します。ただし、評価は単一の実行スレッドの範囲で行われます。具体的に言うと、AとBを評価するための命令が交互に混じる可能性があります。
- AとBの評価が順序付けされるが評価順が不定である場合。この場合AとBの評価順は予測できませんが、同時に評価されることはありません。同じ式が後で再度評価されるときに同じ順序で評価されるとは限りません。
[編集] 規則
1) Full expression (他の式の一部でない式。その大部分は式ステートメントである) のすべての値の計算と副作用は次のfull expressionに先行します。
2) あらゆる演算子のオペランドの値の計算は、そのオペランドの結果の値の計算に先行します。副作用についてはこの限りではありません。
3) 関数呼出し式の、引数のすべての値の計算と副作用は、関数の本体の全ての式とステートメントの実行に先立って評価されます。インライン関数であるかどうかに関わらず、この規則は適用されます。また、明示的に関数呼出し構文が使用されているかどうかに関わらず、この規則は適用されます。
4) 組み込みポストインクリメント・ポストデクリメント演算子の値の計算はその副作用の評価に先行します。
5) 組み込みプリインクリメント・プリデクリメント演算子の副作用の評価は、値の計算に先行します。これは組み込みプリインクリメント・プリデクリメント演算子が複合代入演算子として定義されている為です。
6) 組み込みAND演算子&&とOR演算子||の左辺で行われる全ての値の評価と副作用は右辺で行われる値の評価と副作用の全てに先行します。
7) ?:演算子の最初のオペランドで行われる全ての値の評価と副作用は2番目、3番目のオペランドで行われる値の評価と副作用の全てに先行します。
8) 組み込み代入演算子の副作用(左辺のオペランドの更新)と全ての組み込み複合代入演算子の副作用は、その左辺と両辺の値の計算の後に評価され、その演算子の値の計算(更新されたオブジェクトへの参照の取得)の前に評価されます。
9) 組み込みカンマ演算子,の左辺の全ての値の計算と副作用は右辺の値の計算と副作用の全てに対し先行します。
10) List initializationにおいて、ある初期化節の全ての値の計算と副作用は、その後にある初期化節の値の計算と副作用の全てに先行します。
11) 順序付けされていない2つの関数呼出しは、順序付けされますが、評価順は不定です。プログラムは、その2つの関数呼出しで呼び出される関数の命令が混ぜて実行されたのではなく別個に実行されたのと同様に振る舞います。
12) 割り当て関数(operator new)への呼出しとnew式のコンストラクタの式の間の評価順は不定です。
[編集] 未定義動作
1) あるオブジェクトに対する2つの副作用が順序付けされていない場合、未定義動作となります。
i = ++i + i++; // 未定義動作
i = i++ + 1; // 未定義動作 (i = ++i + 1は問題ありません)
f(++i, ++i); // 未定義動作
f(i = -1, i = -1); // 未定義動作
2) あるオブジェクトに対する副作用の評価と値の計算が順序付けされていない場合、未定義動作となります。
cout << i << i++; // 未定義動作
a[i] = i++; // 未定義動作
[編集] シーケンスポイント規則 (C++11以前)
[編集] 定義
You can help to correct and verify the translation. Click here for instructions.
You can help to correct and verify the translation. Click here for instructions.
[編集] 規則
1)You can help to correct and verify the translation. Click here for instructions.
You can help to correct and verify the translation. Click here for instructions.
You can help to correct and verify the translation. Click here for instructions.
You can help to correct and verify the translation. Click here for instructions.
a
後のシーケンスポイントがある.a
.You can help to correct and verify the translation. Click here for instructions.
a && b
a || b
a ? b : c
a , b
[編集] 未定義動作
1)You can help to correct and verify the translation. Click here for instructions.
i = ++i + i++; // undefined behavior
i = i++ + 1; // undefined behavior
i = ++i + 1; // undefined behavior (well-defined in C++11)
++ ++i; // undefined behavior (well-defined in C++11)
f(++i, ++i); // undefined behavior
f(i = -1, i = -1); // undefined behavior
You can help to correct and verify the translation. Click here for instructions.
cout << i << i++; // undefined behavior
a[i] = i++; // undefined bevahior
[編集] 参考
- 演算子の優先順位式は、そのソース·コード表現から構築される方法を定義している.Original:演算子の優先順位 which defines how expressions are built from their source code representation.The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions. - Cプログラミング言語の評価の順序.Original:評価の順序 in the C programming language.The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.