2011-11-08 1 views
3

は時々私は"if ... ASSERT"はリリースビルドで削除されますか?それはIMOより簡単だから

if (ptr) 
    ASSERT(ptr->member); 

代わりの

ASSERT(!ptr || ptr->member); 

ようなコードを記述します。冗長比較はリリースビルドに残っていますか?

+3

見つけるための一つの方法...それをコンパイルし、参照があります。 –

+0

いいえ、ASSERTのすべてのコードが削除されます。 – Max

+2

アサーションが削除される* in *コードを知っています、@ Max。この質問は、前の比較*も削除されるかどうかを尋ねます。 –

答えて

6

私はあなたのコンパイラに依存していると思います。リリースモードで

ASSERTマクロはptr->memberを評価しないであろうと、コンパイラが出て最適化することささいな表現に解決しますが、あるとしてifの文と関連する比較が残ります。

ただし、条件が副作用を持たないと判断するほどスマートな場合は、ifステートメント全体を最適化する可能性があります。アセンブリにコンパイルすると(/FAオプションを使用)、明確な答えが得られます。

+1

現代のコンパイラは、if()(void)0;同様に無意味な操作ですか?または、私は過度に楽観的かもしれません。 – jbat100

+1

@ jbat100:確かにそうすべきですが、確かめるには1つの方法しかありません。 –

+2

@ jbat100では、条件式によって異なります。質問者の例から、 'ptr'は副作用のある関数で' operator bool() 'をオーバーライドするクラスのインスタンスかもしれません。そうであれば、プログラムの動作が変わるため、条件式を省略することはできません。 –

2

コンパイラが愚かでない限り、はい、トリムされます。

は、コンパイラでこれを書いてみます

if (x); 

それは警告その文は効果がありませんし、私はそれは愚かではない場合、それはコードを削除します、言ったようにあなたを与えます。

確かめたい場合は、コンパイラでコンパイルしてアセンブリを参照できます。

1

最適化は、(ユーザーが)必要な場合にLLVMがそれを削除します。

int main(int argc, char **argv) { 
    if (argc) {} 
    return 0; 
} 

は次のようになります。

define i32 @main(i32 %argc, i8** nocapture %argv) nounwind readnone { 
    ret i32 0 
} 
関連する問題