35

命令型プログラミングのシーケンスポイントは、以前の評価のすべての副作用が実行され、後続の評価からの副作用がまだ実行されていないことが保証される、コンピュータープログラムの実行の任意のポイントを定義します。

これは何を意味するのでしょうか?簡単な言葉で説明してもらえますか?

4

4 に答える 4

54

シーケンス ポイントが発生すると、基本的には、以前のすべての操作が完了したことが保証されることを意味します。

シーケンス ポイントを介在させずに変数を 2 回変更することは、未定義の動作の一例です。

たとえば、i = i++;への 2 つの変更の間にシーケンス ポイントがないため、 は未定義ですi

問題を引き起こす可能性があるのは、変数を 2 回変更するだけではないことに注意してください。実際には、他の用途に関連する変更です。標準では、物事がどのように順序付けられるかについて議論する際に、「値の計算副作用」という用語を使用します。たとえば、式a = i + i++では、i(値の計算) とi++(副作用) を任意の順序で実行できます。

ウィキペディアには、C および C++ 標準のシーケンス ポイントのリストがありますが、最終的なリストは常に ISO 標準から取得する必要があります。C11付録Cから(言い換え):


以下は、標準で説明されているシーケンス ポイントです。

  • 関数呼び出しにおける関数指定子と実引数の評価と実際の呼び出しの間。
  • 演算子&&||、および,;の第 1 オペランドと第 2 オペランドの評価の間。
  • 条件?:演算子の最初のオペランドの評価と、2 番目と 3 番目のオペランドの評価の間。
  • 完全宣言子の終わり。
  • 完全な式の評価と、次に評価される完全な式の間。以下は完全な式です。
    • 初期化子;
    • 式ステートメント内の式。
    • 選択ステートメント (ifまたはswitch) の制御式。
    • whileor do ステートメントの制御式。
    • forステートメントの各式。
    • return ステートメントの式。
  • ライブラリ関数が戻る直前。
  • 各書式付き入出力関数変換指定子に関連付けられたアクションの後。
  • 比較関数の各呼び出しの直前と直後、および比較関数の呼び出しとその呼び出しに引数として渡されたオブジェクトの移動の間。
于 2010-08-26T13:13:49.477 に答える
13

シーケンス ポイントについて注意すべき重要な点は、シーケンス ポイントはグローバルではなく、一連のローカルな制約と見なす必要があるということです。たとえば、声明では

a = f1(x++) + f2(y++);

x++ の評価と f1 の呼び出しの間にシーケンス ポイントがあり、y++ の評価と f2 の呼び出しの間に別のシーケンス ポイントがあります。ただし、f2 が呼び出される前または後に x がインクリメントされるかどうか、また x が呼び出される前または後に y がインクリメントされるかどうかについての保証はありません。f1 が y を変更するか、f2 が x を変更する場合、結果は未定義になります (たとえば、コンパイラが生成したコードが x と y を読み取り、x をインクリメントし、f1 を呼び出し、以前に読み取った値に対して y をチェックし、さらに --if Barney のビデオと商品をすべて探し出して破壊する暴れ回る; 残念ながら、実際にそれを行うコードを生成する実際のコンパイラはないと思いますが、標準では許可されています)。

于 2010-08-26T15:52:57.210 に答える
5

例を使用して paxdiablo の回答を拡張します。

ステートメントを仮定します

x = i++ * ++j;

3 つの副作用があります: i * (j+1)x への結果の代入、i への 1 の加算、および j への 1 の加算です。副作用が適用される順序は指定されていません。i と j は、評価された直後にそれぞれインクリメントされるか、両方が評価されてから x が割り当てられるまでインクリメントされないか、または x が割り当てられるまでインクリメントされません。

シーケンス ポイントは、適用された順序に関係なく、すべての副作用が適用された (x、i、および j がすべて更新された) ポイントです。

于 2010-08-26T15:10:05.000 に答える
4

これは、コンパイラがファンキーな最適化、トリック、マジックを実行する可能性があることを意味しますが、これらのいわゆるシーケンス ポイントで明確に定義された状態に到達する必要があります。

于 2010-08-26T13:18:42.800 に答える