これを行うために gcc コンパイラ フラグに依存することはありません。コンパイラ フラグは、gcc のバージョン間で変更される可能性があり、コンパイラ間で変更されます。Visual C++ で同じコードを 6 か月でデバッグする必要があることに気付くかもしれません...
@CharlesBailey は、変数を使用してこれを行う方法について良い提案をしていextern
ます。変数をモジュール全体に公開したり、静的ストレージに保持したりする必要がない代替手段の 1 つを次に示します。
ステートメントvolatile
のスコープで一時変数を宣言します。if
if (volatile bool dbg = false)
{
do_some_debug_printing_and_checking();
}
これにより、一時変数の範囲が非常に狭くなります。修飾子により、volatile
コンパイラは変数について何も仮定したり、分岐を最適化したりできなくなります。
覚えておくべきことの 1 つは、変数は常にスタックに割り当てられ、関数が終了するまでスタックに保持されるということです。このアプローチとアプローチの両方がextern
機能するはずですが、わずかに異なる (そしておそらく無視できる) トレードオフがあります。
この問題を解決するためにマクロを使用する場合は、コードを本番環境にリリースするときに一時変数を簡単に無効にすることができます。
#ifndef IS_DEBUGGING
# define IS_DEBUGGING 0
#endif
#if IS_DEBUGGING
# define TMP_DBG_FLAG volatile bool dbg_flag = false
#else
# define TMP_DBG_FLAG false
#endif
次に、if
ステートメントを次のように宣言します。
if ( TMP_DBG_FLAG )
{
do_some_debug_printing_and_checking();
}
IS_DEBUGGING を 1 に定義すると、ローカル変数が作成され、volatile と宣言され、保持されます。IS_DEBUGGING を 0 に定義すると、マクロは定数false
に展開され、コンパイラは分岐を最適化します。extern
アプローチについても、非常によく似たことができます。
この数行の追加コードは、TMP_DBG_FLAG を使用する回数とは関係ありません。コードは、大量のifdef
s を使用するよりもはるかに読みやすくなります。マクロは (値を追加することで) 少し安全にすることができますが__LINE__
、これには 3 つのマクロが必要であり、おそらく必要ありません。
#if IS_DEBUGGING
// paste symbols 'x' and 'y' together
# define TMP_DBG_FLAG_SYMCAT0(x,y) x ## y
// need one level of indirection to expand __LINE__...
# define TMP_DBG_FLAG_SYMCAT(x,y) TMP_DBG_FLAG_SYMCAT0(x,y)
# define TMP_DBG_FLAG volatile bool TMP_DBG_FLAG_SYMCAT(dbg_flag_,__LINE__) = false
#else
# define TMP_DBG_FLAG false
#endif