InformIT の David Chisnall の記事「Understanding C11 and C++11 Atomics」から引用した、次の一連のvolatile
メモリへの書き込みについて考えてみましょう。
volatile int a = 1;
volatile int b = 2;
a = 3;
C++98 からの私の理解では、C++98 1.9 に従って、これらの操作を並べ替えることができないということでした。
準拠する実装は、以下で説明するように、抽象マシンの観察可能な動作をエミュレート (のみ) する必要があります ... 抽象マシンの観察可能な動作は、揮発性データへの読み取りと書き込み、およびライブラリ I/O 関数の呼び出しのシーケンスです。
Chisnall は、順序の保存に関する制約は個々の変数にのみ適用されると述べ、適合する実装はこれを行うコードを生成できると書いています。
a = 1;
a = 3;
b = 2;
またはこれ:
b = 2;
a = 1;
a = 3;
C++11 は、C++98 の文言を繰り返します。
準拠する実装は、以下で説明するように、抽象マシンの観察可能な動作を (のみ) エミュレートする必要があります。
volatile
しかし、 s (1.9/8)について次のように述べています。
volatile オブジェクトへのアクセスは、抽象マシンの規則に従って厳密に評価されます。
1.9/12 では、volatile
glvalue (変数a
、b
、およびc
上記を含む) へのアクセスは副作用であると述べており、1.9/14 では、1 つの完全な式 (たとえば、ステートメント) の副作用は、後の副作用の前にある必要があると述べています。同じスレッドで完全な表現。これにより、Chisnall が示した 2 つの並べ替えは無効であると結論付けることができます。なぜなら、それらは抽象機械によって指示された順序付けに対応していないからです。
私は何かを見落としていますか、それともチスナルは間違っていますか?
(これはスレッドの問題ではないことに注意してください。問題は、コンパイラがvolatile
単一のスレッドで異なる変数へのアクセスを並べ替えることが許可されているかどうかです。)