問題タブ [instruction-reordering]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - この実行の並べ替えは可能ですか
ご存知のように、コンパイラまたは CPU は、as-if ルールに従っている場合にのみ、必要に応じて実行を並べ替えることができます。たとえば、次のようなコードがあるとします。
コンパイラまたは CPU は のD = E + F
前に実行される場合がありC = A + B
ます。私はそれを理解することができます。
今日、同僚が C++ でログ ライブラリを構築しようとしました。彼のアイデアは、コンストラクタとデストラクタを使用して、operator<<()
.
基本的に、彼はそのような種類のクラスを提供しました:
今、私はログ ライブラリのユーザーです。私の同僚は、以下のようにライブラリを使用できると私に言いました:
したがって、最初の行が実行されると、コンストラクターが呼び出されるため、ログで「開始」を取得できます。そして、関数が戻ると、のデストラクタlog
が呼び出されるのでend
、ログに記録されます。オブジェクトの助けを借りてlog
、関数の開始と終了を明確に見つけることができます。
クリアで素晴らしいですね。
ただし、投稿の冒頭で述べたように、マシンは必要に応じて並べ替えを行う場合があります。そのため、 のコンストラクターがlog
思ったよりも遅く呼び出されたり、 のデストラクタがlog
思ったよりも早く呼び出されたりして、log
が期待どおりに機能しない可能性があるかどうか疑問に思っています。つまり、コードはfunc
上記のように見えましたが、コンパイルまたは実行すると、実際の順序は次のようになりました。
ところで、クラス内のストリームはLog
、ファイル、共有メモリ、TCP ソケットなど、別の場所に送られます。
それで私は合理的ですか?それとも、この種の並べ替えは決して起こらないのでしょうか? それが起こる可能性がある場合、この種の並べ替えを禁止する手法や、関数の開始と終了を通知できる使用可能なログ ライブラリを提供する手法はありますか?
実際、C++11 で や などの新しいテクニックを聞いたことがstd::atomic
ありstd::atomic_thread_fence
ます。私の理解では、この種の並べ替えが可能である場合、必要なものは... フェンスでしょうか?
可能かどうかは本当にわかりません...
副作用/観察可能な動作について
私の理解では、これは副作用/観察可能な動作です。
なんで?の値A
が変わるからです。
では、次のようにコーディングするとどうなるでしょうか。
したがって、順序は次のようになります。
- のコンストラクタ
log
A = B + C
- のデストラクタ
log
ただし、順序が次のようになる場合:
A = B + C
- のコンストラクタ
log
- のデストラクタ
log
それでいいと思います。なんで?A
副作用/観察可能な動作に関するの値は変更されないためです。どの順序を取っても、その値は常に になりますB + C
。
私は正しいですか?私が正しければLog
、期待どおりに機能しないことを意味すると思います。
アップデート
A = B + C
の値が変更されるという副作用がありますが、これはA
観察可能な動作ではありません。