シナリオ 1 の場合、コンパイラは、あなたが言及した並べ替えを実行するべきではありません。シナリオ 2 の場合、答えは以下によって異なります。
b
および変数が現在の関数の外で見えるかどうかc
(非ローカルであるか、アドレスが渡されているかのいずれかによって)
volatile
誰と話しているか (明らかに、C/C++ における文字列の扱いについて意見の相違があるようです)
- コンパイラの実装
したがって(私の最初の答えを和らげます)、シナリオ2の特定の動作に依存している場合、特定のプラットフォームでの動作がどのようなものによって決定される移植不可能なコードとして扱う必要があると思います.実装のドキュメントが示す可能性があります (ドキュメントがそれについて何も述べていない場合は、動作が保証されていないことになります。
C99 5.1.2.3/2 から「プログラムの実行」:
揮発性オブジェクトへのアクセス、オブジェクトの変更、ファイルの変更、またはこれらの操作のいずれかを行う関数の呼び出しはすべて、実行環境の状態の変化である副作用です。式の評価により、副作用が生じる場合があります。シーケンスポイントと呼ばれる実行シーケンスの特定のポイントでは、以前の評価のすべての副作用が完了し、後続の評価の副作用は発生していません。
...
(パラグラフ 5) 適合する実装に関する最小要件は次のとおりです。
- シーケンス ポイントでは、以前のアクセスが完了し、後続のアクセスがまだ発生していないという意味で、揮発性オブジェクトは安定しています。
volatile
Herb Sutter がC/C++ で必要なアクセスの動作について述べていることの一部を次に示します (「 volatile
vs. volatile
」http://www.ddj.com/hpc-high-performance-computing/212701484から) :
近くの通常の読み取りと書き込みはどうですか?最適化できない読み取りと書き込みの周りでそれらを並べ替えることができますか? 現在、C/C++ コンパイラの実装はさまざまであり、すぐに収束する可能性は低いため、実用的な移植可能な答えはありません。たとえば、C++ 標準の 1 つの解釈では、通常の読み取りは C/C++ の揮発性の読み取りまたは書き込みを介してどちらの方向にも自由に移動できますが、通常の書き込みは C/C++ の揮発性の読み取りまたは書き込みを介してまったく移動できないとされています。 C/C++ volatile は、順序付けられたアトミックよりも制限が少なく、制限が厳しくなります。一部のコンパイラ ベンダーはその解釈をサポートしています。揮発性の読み取りまたは書き込みをまったく最適化しないものもあります。さらに、独自の優先セマンティクスを持っているものもあります。
そして、価値のあるものとして、Microsoft は C/C++volatile
キーワードについて次のことを文書化しています (Microsoft-sepcific として):
揮発性オブジェクトへの書き込み (揮発性書き込み) にはリリース セマンティクスがあります。命令シーケンスで揮発性オブジェクトへの書き込みの前に発生するグローバルまたは静的オブジェクトへの参照は、コンパイルされたバイナリでの揮発性書き込みの前に発生します。
揮発性オブジェクトの読み取り (揮発性読み取り) には、取得セマンティクスがあります。命令シーケンスで揮発性メモリの読み取り後に発生するグローバルまたは静的オブジェクトへの参照は、コンパイルされたバイナリでの揮発性読み取りの後に発生します。
これにより、揮発性オブジェクトをマルチスレッド アプリケーションでのメモリのロックと解放に使用できます。