可変引数リストを取るデバッグ専用関数を作成するにはどうすればよいですか? printf() のように

私は今でも昔ながらの方法で、no-op または可変引数リストを使用した関数呼び出しに対応するマクロ (以下の XTRACE) を定義しています。内部で vsnprintf を呼び出して、printf 構文を維持できるようにします。

#include <stdio.h>

void XTrace0(LPCTSTR lpszText)
{
   ::OutputDebugString(lpszText);
}

void XTrace(LPCTSTR lpszFormat, ...)
{
    va_list args;
    va_start(args, lpszFormat);
    int nBuf;
    TCHAR szBuffer[512]; // get rid of this hard-coded buffer
    nBuf = _vsnprintf(szBuffer, 511, lpszFormat, args);
    ::OutputDebugString(szBuffer);
    va_end(args);
}

次に、典型的な #ifdef スイッチ:

#ifdef _DEBUG
#define XTRACE XTrace
#else
#define XTRACE
#endif

これはかなりクリーンアップできますが、基本的な考え方です。


これは、C++ で出力をデバッグする方法です。 'dout' (デバッグアウト) を次のように定義します:

#ifdef DEBUG
#define dout cout
#else
#define dout 0 && cout
#endif

コードでは、'cout' と同じように 'dout' を使用しています。

dout << "in foobar with x= " << x << " and y= " << y << '\n';

プリプロセッサが 'dout' を '0 &&cout' に置き換える場合、<<は &&よりも優先順位が高く、&&の短絡評価により行全体が 0 に評価されることに注意してください。0 は使用されないため、コンパイラはコードをまったく生成しません。


これは私が C/C++ で行っていることです。まず、varargs を使用する関数を作成します (Stu の投稿のリンクを参照してください)。次に、次のようにします:


 int debug_printf( const char *fmt, ... );
 #if defined( DEBUG )
  #define DEBUG_PRINTF(x) debug_printf x
 #else
   #define DEBUG_PRINTF(x)
 #endif

 DEBUG_PRINTF(( "Format string that takes %s %s\n", "any number", "of args" ));

覚えておく必要があるのは、デバッグ関数を呼び出すときに二重括弧を使用することだけです。これにより、DEBUG 以外のコードでは行全体が削除されます。