2009-08-20 17 views
4

私はC++の関数debugPrint(int foo)を持っているとします。どのようにすれば、リリースビルドから最も簡単に取り除くことができますか?私は#ifdefsでdebugPrintを呼び出す際に、本当に時間がかかるので、それを囲む必要はありません。一方、私は、コンパイラがその関数へのすべての呼び出しを取り除き、リリースビルドからの関数自体を100%確実に除去したいと考えています。ストリッピングは、関数呼び出しの結果として呼び出されたパラメータでも呼び出されます。たとえば、debugPrint(getFoo());その場合、私はgetFoo()呼び出しを取り除きたい。関数のインライン展開はオプションになる可能性があると理解していますが、インライン展開はサポートされているとは限りません。C++でコンパイル時にデバッグコードを取り除く方法は?

+1

'からgetfoo()' 'でdebugPrint(からgetfoo())を除去する唯一の方法は、 'マクロを使用することです。しかし、それはあなたがプログラムがデバッグとリリースの設定において異なって振る舞うという点で、それにつながります。これは本当に危険です。 –

+1

getFoo()が変数fooの値を取得する以外にいくつかの隠されたロジックを持っていると危険です。しかし、それは悪いコーディングです。 – juvenis

答えて

13

使用conditinalコンパイルおよびマクロ:

#ifdef _DEBUG 
    #define LOG(x) debugPrint(x) 
#else 
    #define LOG(x) 
#endif 

デバッグビルドの_DEBUGを定義し、リリースビルドのためにそれを定義しません。今すぐリリースビルドで

LOG(blahbhahblah); 

は空の文字列に展開されます。パラメータは評価されず、放出されるコードには含まれません。

デバッグビルドで定義され、_DEBUGの代わりにリリースで定義されていない既存のプリプロセッサシンボルを使用できます。

+0

ええと..まさに何のマクロがありますか? – Newtopian

+6

これは危険でエラーが発生しやすいです。 'int x = 0; LOG(x + = 2); use(x); 'は、" release "または" debug "モードがオンになっていると、動作が異なります。 – LiraNuna

+2

はい、そうです。この世界では何も無料ではありません。 – sharptooth

1

これまで、プリプロセッサでこれまで何かしてきました。関数をインラインにします

+1

Err、有効な 'debugPrintf( "hello");'むしろ無効な '( "hello"); ? – paxdiablo

+1

@Pax、それは完全に有効です。 – strager

+1

警告を発する可能性のあるもの。 '(void)(" hello ")'が適切だと思われます。しかし、間違っている:debugPrint(GetFoo())は依然として明示的に要求されていないこのマクロでGetFoo()を呼び出します。 – MSalters

7

にすべてのデバッグ行を削除します基本的に

#ifndef DEBUG 
#define debugPrint 
#endif 

、および関数内のように、#1 IFDEF年代を持っている:オプティマイザは取り除くことができます

inline void debugPrint(whatever_t wtvr) 
{ 
    #ifdef DEBUG 
     Logger::log(wtvr); 
    #endif 
} 

その方法コードをきれいに保ちながら空の関数を呼び出します。

+2

これは、関数パラメータが評価されないことを保証しますか? – sharptooth

+0

これは他の要件には役立ちません(wtvrを計算するために評価する必要のあるコードが生成されない場合) –

+3

@sharptoothこれらは、この解決策で評価する必要があります。しかし、評価がプログラムの動作(つまり副作用)を変更した場合、ロガー機能を呼び出すだけでロギング以上のことができるという問題があります。 – strager

1

#ifdef _DEBUG 
#define debugPrint(x) _debugPrint(x) 
void _debugPrint(int foo) { 
    // debugPrint implementation 
} 
#else 
#define debugPrint(x) 
#endif 
2

@シャープトゥースの答えが良いです。

#ifndef NDEBUG 
   #define LOG(x) debugPrint(x) 
#else 
   #define LOG(x) 
#endif 

NDEBUGマクロが定義されている場合、その後:私は正常に作る一つのマイナーチェンジでは、しかし、デバッグマクロが定義されてある場合NDEBUGマクロが定義されてないある場合は、デバッグを無効にするのではなく、することです前提条件や事後条件のようなものを宣言するのに、あるいは複雑な論理の結果を明確にするのにも、私はかなり自由に使う傾向がありますが、コンパイルからも脱落してしまいます。C assertこれは、 "no debugging"の標準マクロです。また、NDEBUGマクロは、リリースビルドですでに定義されている必要があります。

参照:http://www.opengroup.org/onlinepubs/009695399/functions/assert.html

関連する問題