1

たとえば、次のような左辺値がない場合にコンパイラが何をするか想像できません。私の直感では、コンパイラは最適化のためにこの行をコンパイルから破棄し、最適化が削除されるとどうなるでしょうか? レジスタを使用して操作を行いますか? または、関数呼び出しのように動作するため、パラメーターがスタックに渡され、使用されているメモリが解放済みとしてマークされますか? それともそれを NOP 操作に変換しますか? VS++ デバッガーを使用して何が起こっているかを確認できますか? 助けてくれてありがとう。

4

2 に答える 2

1

あなたが与える例では、操作を破棄します。操作に副作用がないことがわかっているため、正しいプログラムを生成するためにステートメントを実行するコードを発行する必要はありません。最適化を無効にしても、コンパイラは引き続きコードを出力する可能性があります。最適化を有効にすると、コンパイラもコードを出力する可能性があります。これは完全ではありません。

/FAscMicrosoft コンパイラのコマンド ライン オプションを使用して、コンパイラが出力するコードを確認できます。このオプションは、関連するソース コードが散在するコンパイラのオブジェクト コード出力を含むリスティング ファイルを作成します。

デバッガーで「逆アセンブリーの表示」を使用して、コンパイラーによって生成されたコードを表示することもできます。

「ビューの逆アセンブリ」または/FAsc最適化されたコードのいずれかを使用すると、コンパイラから出力されたコードが表示されないと予想されます。

于 2013-03-08T23:35:52.543 に答える
0

numberが整数型 (not ) の通常の変数であると仮定するとvolatile、有能な最適化コンパイラ (Microsoft、Intel、GNU、IBM など) はまったく何も生成しません。ではない、nopレジスタが使用されていないなど。

(「デバッグ ビルド」で) 最適化が無効になっている場合、コンパイラはコードからの副作用がないことを認識しないため、「要求されたことを実行する」可能性があります。この場合、値はレジスタにロードされ、右に 1 回シフトされます。この結果はどこにも保存されません。コンパイラは、最適化ステップの 1 つとして「無駄なコードの削除」を実行します。どのステップかはわかりませんが、この種の比較的単純なことについては、コンパイラがかなり基本的な最適化設定で判断することを期待しています。ループが関係する場合など、コンパイラは、より高度な最適化設定が有効になるまでコードを最適化しない場合があります。

コメントで述べたように、変数が揮発性である場合、numberコンパイラはメモリを読み取る必要があるため、によって表されるメモリの読み取りを行う必要がありvolatileます。

Visual Studio で「逆アセンブリを表示」すると、コンパイラが生成したコードが表示されます。

最後に、これが C++ の場合、変数が通常の整数型ではない可能性もあります。operator>>このコードがコンパイラによって認識されたときに関数が呼び出されています。この関数は、結果を返す以外に副作用がある可能性があるため、実行する必要があります。しかし、これは C では当てはまりません。演算子のオーバーロードがないためです。

于 2013-03-09T01:49:24.927 に答える