如何创建一个只接受变量参数列表的调试函数?喜欢printf()

hyp*_*gic 38 c c++ c-preprocessor

我想用一个相同的参数来创建一个调试日志功能printf.但是在优化构建期间可以由预处理器删除的一个.

例如:

Debug_Print("Warning: value %d > 3!\n", value);
Run Code Online (Sandbox Code Playgroud)

我查看了可变参数宏,但并非所有平台都可以使用.gcc支持他们,msvc不支持他们.

小智 23

我仍然按照旧的方式,通过定义一个宏(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);
}
Run Code Online (Sandbox Code Playgroud)

然后是一个典型的#ifdef开关:

#ifdef _DEBUG
#define XTRACE XTrace
#else
#define XTRACE
#endif
Run Code Online (Sandbox Code Playgroud)

嗯,这可以清理很多,但这是基本的想法.


小智 21

这就是我在C++中调试打印输出的方法.像这样定义'dout'(调试输出):

#ifdef DEBUG
#define dout cout
#else
#define dout 0 && cout
#endif
Run Code Online (Sandbox Code Playgroud)

在代码中我使用'dout'就像'cout'.

dout << "in foobar with x= " << x << " and y= " << y << '\n';
Run Code Online (Sandbox Code Playgroud)

如果预处理器将'dout'替换为'0 && cout',请注意<<具有比&&更高的优先级,并且&&的短路评估使得整行评估为0.由于不使用0,编译器根本不生成代码为那条线.

  • 当未激活debug时,这会生成警告(gcc -Wall):"warning:statement无效[-Wunused-value] 0 && std :: cout <<"test"; (3认同)

Gra*_*row 11

这是我在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" ));
Run Code Online (Sandbox Code Playgroud)

所有你必须记住的是在调用debug函数时使用double-parens,并且整行将在非DEBUG代码中被删除.


hyp*_*gic 5

啊,vsprintf() 是我缺少的东西。我可以使用它将变量参数列表直接传递给 printf():

#include <stdarg.h>
#include <stdio.h>

void DBG_PrintImpl(char * format, ...)
{
    char buffer[256];
    va_list args;
    va_start(args, format);
    vsprintf(buffer, format, args);
    printf("%s", buffer);
    va_end(args);
}
Run Code Online (Sandbox Code Playgroud)

然后将整个事情包装在宏中。