10,000行のC++コードがあるとします。このコードの200行はテスト用です(たとえば、プログラムをチェックしてエラーメッセージを表示します)。
C++でコードの一部の行を無視または検討する方法はありますか(おそらく プリプロセッサ キーワードを使用)?
macrosおよび#ifdef
チェックを使用します。例えば:
#ifdef MY_CONTROL_MACRO
...
#endif
このスコープ内のコードは、MY_CONTROL_MACRO
マクロを既に定義している場合にのみコンパイルされます。
このようなマクロを定義するには、次のことができます
#define MY_CONTROL_MACRO
をコードに追加します。または、MY_CONTROL_MACRO
をProject > Properties > C/C++ > Preprocessor > Preprocessor Definitions
に追加します。または、-DMY_CONTROL_MACRO
を使用してコードをコンパイルします。詳しくは here をご覧ください。
このブロックは条件付きグループと呼ばれます。 MACROが定義されている場合にのみ、プリプロセッサの出力に制御テキストが含まれます。 MACROが定義されていれば条件は成功し、定義されていなければ失敗すると言います。
条件内の制御テキストには、前処理ディレクティブを含めることができます。これらは、条件が成功した場合にのみ実行されます。条件グループは他の条件グループ内にネストできますが、完全にネストする必要があります。つまり、「#endif」は常に最も近い「#ifdef」(または「#ifndef」、「#if」)と一致します。また、あるファイルで条件付きグループを開始し、別のファイルで終了することはできません。
高度なifdef-else-endif
スタイルも使用できます。
#ifdef MY_CONTROL_MACRO
... // this part will be valid if MY_CONTROL_MACRO is defined
#else
... // this part will be valid if MY_CONTROL_MACRO is NOT defined
#endif
コードを「#ifdef ...#endif」で囲み、コンパイラオプションを使用してフラグを設定します。
#ifdef MYTEST_ONLY_FUNCTIONALITY_ENABLED
...
#endif
その後、コンパイラオプションを使用してこのコードを含めることができます。たとえば、GCCの場合:
-DMYTEST_ONLY_FUNCTIONALITY_ENABLED
正直なところ、このアプローチは大規模なプロジェクトでは一般的にあまりメンテナンスが難しいと思います。可能であれば、テスト専用コードを完全に独立したライブラリに移動して(この条件ロジックなしで)単純にリンクする方が一般的です非テストバイナリではなく、テストバイナリにコードを記述します。また、デバッグモードと非デバッグモードの両方で他の各ライブラリをコンパイルする必要がなくなります。
これは何 #ifdef
は
あなたが置く
#ifdef TESTS
... test code ...
#endif
そして、コンパイラオプションに渡して、テストパーツをコンパイルするかどうかを決定できます。たとえば、g ++では
g++ -DTESTS ...
プリプロセッサガードの使用は、間違いなく最も柔軟で一般的なアプローチです。ただし、可能であれば、ifステートメントを使用することをお勧めします。たとえば、代わりに
void example(int a){
int some_local;
...
#ifdef _DEBUG
std::cout << "In function " << __FUNCTION__ << "(" << a <<")" << std::endl;
#endif
....
}
ENABLE_DEBUGが0または非ゼロに定義されていると仮定すると、私は
void example(int a){
int some_local;
...
if(ENABLE_DEBUG) std::cout << "In function " << __FUNCTION__ << "(" << a <<")" << std::endl;
...
}
ENABLE_DEBUGは定数であるため、ENABLE_DEBUGが0の場合、コンパイラは保護するステートメントのコードを生成しません。では、なぜ#ifdefの代わりにこのメソッドを使用するのですか?
明らかに、このアプローチはメソッド/関数本体内のデバッグステートメントに対してのみ機能します。
existing規約に従って、NDEBUG
マクロを使用します。すべての一般的なコンパイラは、releaseビルドに対してこのマクロを定義し、debugビルドに対しては定義しません。
このマクロは元々assert(3)
の出力を制御するために存在し、 POSIX標準では および少なくともC89以降、そのように定義されています。
#ifndef
を使用してテストを元に戻す必要があることに注意してください。
例:
#ifndef NDEBUG
/* Debugging code */
std::cerr << "So far we have seen " << unicorns << " unicorns" << std::endl;
#endif
追伸gcc
/g++
を使用すると、-g
をコマンドラインに追加してデバッグビルドを実行できます。
プリプロセッサの#defineと#ifを使用します
コンパイラに応じて、デフォルトでいくつかの変数、つまりNDEBUG(非デバッグ用)またはDEBUGを使用できるようにする必要があります
コードで変数を自分で定義できます
#define MY_VARIABLE
次のように使用します
#ifdef MY_VARIABLE
//code that compiles only if MY_VARIABLE is defined
printf("test output here");
#else
//code that compiles only if MY_VARIABLE is NOT defined
printf("MY_VARIABLE is not defined");
#endif
詳細については、オンラインで検索してください
#define, #if, #ifdef, #ifndef
テストコードを囲む#ifdef DEBUG
。
#if DEBUG
....
#endif
進む方法は、コンパイラに渡されるか、ヘッダー「config.h」から取得されるdefine
でプリプロセッサディレクティブを使用することです。
#if defined(DEBUG) // or #ifdef DEBUG
// Debug code
#endif
ソースコードのどこでも使用しないようにするには:
#if defined(DEBUG)
My_Debug_function(some_variable)
#endif
ヘッダーで行うことができます
#if !defined(DEBUG) // or #ifndef DEBUG
# define My_Debug_function(some_variable) do { static_cast<void>(some_variable); } while (false) /* Do nothing */
#endif
したがって、My_Debug_function
ほとんど通常。