C++03 標準 1.9/5 による
整形式プログラムを実行する適合実装は、同じプログラムと同じ入力を持つ抽象マシンの対応するインスタンスの可能な実行シーケンスの 1 つと同じ観測可能な動作を生成するものとします。
「の1つとして」の部分がわかりません。
特定のプログラムと特定の入力があり、プログラムに未定義の動作が含まれていない場合、観察可能な動作が異なるのはなぜですか? 「可能な実行シーケンスの 1 つ」とはどういう意味ですか?
C++03 標準 1.9/5 による
整形式プログラムを実行する適合実装は、同じプログラムと同じ入力を持つ抽象マシンの対応するインスタンスの可能な実行シーケンスの 1 つと同じ観測可能な動作を生成するものとします。
「の1つとして」の部分がわかりません。
特定のプログラムと特定の入力があり、プログラムに未定義の動作が含まれていない場合、観察可能な動作が異なるのはなぜですか? 「可能な実行シーケンスの 1 つ」とはどういう意味ですか?
C ++では、特定のことが実装に任されています。たとえば、あなたが書くとき
int x = f(a) + f(b);
実装は、最初にf(a)を呼び出すか、最初にf(b)を呼び出すかを選択できます。
検討:
x = f() + g();
これにより、次の 2 つの実行シーケンスが可能になります。
__temp1 = f(); /*or*/ __temp1 = g();
__temp2 = g(); /*or*/ __temp2 = f();
x = __temp1 + __temp2; /*or*/ x = __temp2 + __temp1;
標準では、これらのうちどれを実行する必要があるかは指定されていません。プログラムは、これら 2 つのいずれかが実行されたかのように動作する必要があります。f()
とg()
に副作用がある場合、プログラムは 2 つの異なる観察可能な動作のいずれかを持つことができます。
C++ 標準では、一部の式の評価順序が定義されていません。たとえば、次のようになります。
proc( a(), b() );
a() と b() の両方が proc() の前に評価される必要がありますが、a() は b() の前または後に評価されます。したがって、2 つの有効な実行シーケンスがあり、a() と b() に副作用 (print ステートメントなど) がある場合、コンパイラがどちらを使用したかがわかります。
(評価順序に関するこの自由は、コンパイラがより効率的なコードを生成できるようにすることを目的としています。実際に最新のマシンで役立つかどうかは、議論の余地があります。)
他の人がすでに述べたように部分式が評価される不特定の順序に加えて、C ++ 11はスレッド化を追加することに注意してください。これにより、実行の順序がさらに不確定になります。
たとえば、2つのスレッドを実行していて、それぞれが「スレッドA」または「スレッドB」を出力するだけの場合、これらの出力が生成される順序は完全に指定されていません。すべての「スレッドA」出力の後にすべての「スレッドB」出力が続く場合、またはその逆の場合、または任意にインターリーブされる場合があります(インターリーブの可能性が高くなります)。