我想用一个相同的参数来创建一个调试日志功能printf
.但是在优化构建期间可以由预处理器删除的一个.
例如:
Debug_Print("Warning: value %d > 3!\n", value);
我查看了可变参数宏,但并非所有平台都可以使用.gcc
支持他们,msvc
不支持他们.
我仍然按照旧的方式,通过定义一个宏(XTRACE,下面),它与无操作或带有可变参数列表的函数调用相关.在内部,调用vsnprintf,以便您可以保留printf语法:
#includevoid 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
在代码中我使用'dout'就像'cout'.
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函数时使用double-parens,并且整行将在非DEBUG代码中被删除.