2012-02-17 9 views
2

コンパイラはこのif文を削除しますか?コンパイラは常にゼロに評価されるブロックを削除しますか?

#define DEBUG 0 
int main(int argc, char ** argv) 
{ 
    if(DEBUG) 
    { 
     ... 
    } 
    return 0; 
} 

私はこれをGoogleに試みて、stackoverflowを検索しましたが、情報を見つけることができなかったため、検索条件が悪いと思います。

これが最適化されていれば、最適化について知りたいことを読んでみたいと思いますか?

コンスタンタン

+10

コンパイラに出力のアセンブリリストを生成するように依頼することで、いつでも自分自身を見つけることができます。 –

+1

あなたのコンパイラとそのオプションによって異なりますが、おそらくブロック全体が削除されます。あなたが必要とするコードを実際に追加したり削除したりするのであれば、ifを使用する代わりに#ifdefを使って条件付きコンパイルを使用します。 – Dampsquid

+0

コンパイラが標準によってxまたはyを実行できるようになると、xを実行するコンパイラとyを実行するコンパイラが常に見つかります。だから、このような質問をするのは、常に「試してみてください」と答えただけです。 – PlasmaHH

答えて

3

コンパイラが最適化できるかどうかわかりません。この状況では副作用がないので、コードのセマンティクスを変更しなくても安全に削除できます。

いずれにしても、推測はうまくいかず、最適化に頼ってもうまくいきません。

コードブロックではなく#ifdef .. #endifブロックを使用してください。

#define DEBUG 

#ifdef DEBUG 
    ... 
#endif 

このようにすれば、確実な結果が得られます。

+0

私はこのアプローチについても考えていましたが、#ifdefでソースファイルを膨らませたくありませんでした。 (人間の読書のために)。ありがとうジャック。 – Constantin

+1

私は通常、それらをコードと一緒にインデントして、悪い視覚的なアプローチをしないようにしています。しかし、それは個人的な味の問題です – Jack

3

推測する必要はありません。デバッガがアセンブリ命令を監視しながらコンパイルして実行します。問題の行に実際のコードが生成されているかどうかを確認するために、アセンブリに精通している必要はありません。

3

はい、まともなC/C++コンパイラは、そのようなifブロックを削除します。

2

すべてのコンパイラが同じものを同じ方法で最適化するという普遍的な声明を作成することはできません。同様に、今日起こっているかもしれないコンパイラは、将来のバージョンではそうでないかもしれません。

はい、今日、多くのコンパイラがこれを行うことができますが、そうすることはできませんが、それを計画したり期待したりする必要はありません。あなたがそのコードをそこに置こうと思っていなければ、それをコメントアウトし、ifdefをコメントアウトして削除してください。

他の人に言われているように、試してみてください。あなたが何かをデバッグしていて、これが起こっているかどうか疑問に思っているなら、単に見て見つけてください。

+1

このケースでは、工業強度のコンパイラがこれまで失敗することはないと完全に安全だと主張しますこれを最適化する。一方、DEBUGは、誰かが不注意に変数を作って、コマンドラインで設定可能なものです。その意味では、面倒かもしれません。 – jkerian

+0

私は、より一般的な "Will A Compiler Remove"の部分があまりにも開いて曖昧であると話していました。デバッグという言葉は、例えば、どのようなコマンドラインオプション(最適化を含む)が使用されているかを実際には知りませんが、デバッグのためにコンパイルするときには、全ての最適化をスキップして、そういうもの。 –

+0

@dwelch、洞察に感謝します。 2番目のコメントをさらに説明できますか? #defineデバッグ悪い練習をしていますか?ありがとうございました。 – Constantin

1

あなたのコンパイラアセンブリの出力でそれを確認する良い答えがあります。私は時々、私にとって非常に便利です似たイディオムを共有したいと思います:

int main(int argc, char ** argv) 
{ 
    const bool bDebug = false; 
    if(bDebug) 
    { 
     ... 
     LOG(""); /// some heavy loging here 
    } 
    return 0; 
} 

はので、私は私のコードでは、いくつかの関連する場所で-sの場合、このようなを残し、そして私が何か悪い起こったが、私はステップというバグレポートを取得するとき私はいくつかの大きな配列/データ構造を出力する必要があるとき、私はデバッガのbDebug変数(実際には私はそれらの名前をbVerbose)から変更して、そのようなIF-sを入力できるようにします。重いロギングを追加するためにコードを再コンパイルする必要はありません。

関連する問題