この単純なコードを考えてみましょう:
void g();
void foo()
{
volatile bool x = false;
if (x)
g();
}
への潜在的な呼び出しgcc
もclang
最適化もされていないことがわかりg
ます。これが私の理解で正しいです:抽象マシンは、と仮定することでvolatile
一定の折りので変数は、(例えば、ハードウェア・マッピングされたことに起因する)いつでも変更される可能性false
に初期化をif
チェックは間違っているだろう。
しかし、MSVCはへの呼び出しをg
完全に排除します(volatile
ただし、読み取りと書き込みを維持します!)。これは標準に準拠した動作ですか?
背景:デバッグ出力をオンザフライでオン/オフできるようにするために、この種のコンストラクトを時々使用します:コンパイラは常にメモリから値を読み取る必要があるため、デバッグ中に変数/メモリを変更すると、それに応じて制御フローが変更されます。MSVC出力は値を再読み取りしますが、それを無視します(たぶん、定数の折りたたみやデッドコードの除去のため)、これはもちろん、ここでの私の意図を無効にします。
編集:
読み取りと書き込みの排除については、
volatile
ここで説明します。コンパイラーがローカルの揮発性変数を最適化することを許可されていますか?(ネイサンに感謝!)標準は、これらの読み取りと書き込みが発生する必要があることを十分に明確に考えています。しかし、その議論は、コンパイラーがそれらの読み取りの結果を当然のこととして受け取り、それに基づいて最適化することが合法かどうかをカバーしていません。私はこれが標準では不十分/不特定であると思いますが、誰かが私を間違っていると証明したら私は幸せです。もちろん
x
、問題を回避するために非ローカル変数を作成することもできます。この質問は、好奇心から外れています。