3

私は他の誰かが書いたコードを見ています、そしてそれはタイプのたくさんのデバッグセクションを持っています

if(0) { code }

またif(1) { code }

またif(false) { code }

さえあります

#if(0)
#endif

(しかし、灰色にはなりませんでした-私はそうすべきだと思いました)

#if 0これらをいくつか(または)に置き換えると#ifdef _DEBUG、コードを最適化することは可能ですか?-または-違いはありませんか?

これらのセクション内のコードがグレー表示されているのを見て、このコードがリリース実行可能ファイルから削除されていると思ったので、役立つと思います...したがって、高速になります。本当 ?

私が考えているコードは、何度も呼び出される可能性のある関数の内部にあります...

編集:私が参照しているコードは何百万回も実行されています。if(0)の内容が無視されることを認識しています...

また、テストを0から1に切り替えることで、問題を簡単にデバッグできるという利点も認識しています...

私の質問は、if(0)がオーバーヘッドを追加しない場合、テストを何百万回も追加しているという事実です...このコードの所要時間を短縮できるすべてのことを理解しようとしています。

4

5 に答える 5

2

これらのIF内に配置された式が定数であり、コンパイル時に決定可能である場合は、コンパイラーが既にそれらをコードから削除していることをほぼ確信できます。

もちろん、デバッグモードでコンパイルする場合、および/または最適化レベルをゼロに設定している場合、コンパイラはそれをスキップしてそれらのテストを終了する可能性がありますが、単純なゼロ/ 1 /真/偽の値では、ほとんどありません。 。

コンパイル時定数ブランチの場合、コンパイラーがデッドブランチを削除したことを確認できます。

次のような複雑に見えるケースも削除できます。

const int x = 5;

if( 3 * x * x < 10 ) // ~ 75 < 10
{
    doBlah(); // skipped
}

ただし、Xにその「const」マーカーがないと、式の値はコンパイル時に決定できない可能性があり、実際の最終製品に「リーク」する可能性があります。

また、次のコードの式の値は、必ずしもコンパイル時定数ではありません。

const int x = aFunction();

if( 3 * x * x < 10 ) // ~ 75 < 10
{
    doBlah(); // skipped
}

Xは定数ですが、関数からの値で初期化されます。Xは、コンパイル時に決定できない可能性があります。実行時に、関数は任意の値を返す可能性があります*)。そのため、コンパイラーはXが不明であると想定する必要があります。

したがって、可能性がある場合は、プリプロセッサを使用してください。コンパイラがすでにそれを知っていたので、些細なケースではあまり効果がありません。しかし、ケースは必ずしも些細なことではなく、変更が頻繁に発生することに気付くでしょう。オプティマイザが値の推定に失敗すると、たとえそれが死んでいたとしても、コードを残します。一方、プリプロセッサは、コンパイルおよび最適化される前に、無効にされたセクションを削除することが保証されています。また、プリプロセッサを使用して少なくともコンパイルを高速化できます。コンパイラ/オプティマイザは、定数/計算/チェックブランチなどをトレースする必要がありません。

*)コンパイルと最適化の段階で実際に戻り値を決定できるメソッド/関数を作成することができます。関数が単純でインライン化されている場合、その結果値はいくつかのブランチとともに最適化される可能性があります。 if-0句の削除にある程度頼ることができたとしても、インライン化にそれほど頼ることはできません。

于 2013-02-02T01:23:19.700 に答える
1

それは本当です(ビルド設定とプリプロセッサによって異なります)。

デバッグコードを#ifdef _DEBUG(または同様のものに)配置することは、これらをリリースビルドから完全に除外するための標準的な方法です。通常、デバッグビルドは#defineそれを行いますが、リリースビルドは行いません。

通常、適切な最適化フラグが与えられている場合、コンパイラーは、などのコードも削除する必要がif (0)ありますが、これにより、コンパイラーとプログラマーに余分な作業がかかります(すべてを変更する必要があります!)。私は間違いなくこれをプリプロセッサに任せます。

于 2013-02-02T01:21:55.753 に答える