__va_args__

来源:互联网 发布:国动网络董事长卢杰 编辑:程序博客网 时间:2024/06/07 11:05

  使用标准的方法打印调试信息有时候不是很方便, 例如Qt编程, 在调试已有的代码时, 我想在打印调试信息的地方, 把代码位置也打印出来以方便定位错误, 或者需要在调试信息前面加一个前辍, 好方便在调试信息太多的时候可以用grep过滤一下, 仅显示本模块的调试信息, 这时就需要一个一个地修改已有的qDebug, 使其成为以下形式:
  qDebug( “[模块名称] 调试信息 File:%s, Line:%d”, FILE, LINE );
  这样的修改比较烦人, 而且一不小心会遗漏某个没改的…

  为了能方便的管理调试信息的输出,一个比较简单的方法就是自已定义一个打印调试信息的宏, 然后替换原来的,废话就不多说了,直接给出一个现成的,下面是一个例子, 我用WiFi表示当前代码的模块名称,我要求在模块中的所有调试信息前面均带有[WiFi]前辍,这样我就能方便地只需使用命令行 | grep “[WiFi]”来过滤掉来自其它模块的调试信息了:

#define qWiFiDebug(format, ...) qDebug("[WiFi] "format" File:%s, Line:%d, Function:%s", ##__VA_ARGS__, __FILE__, __LINE__ , __FUNCTION__);__VA_ARGS__ 是一个可变参数的宏,很少人知道这个宏,这个可变参数的宏是新的C99规范中新增的,目前似乎只有gcc支持(VC6.0的编译器不支持)。宏前面加上##的作用在于,当可变参数的个数为0时,这里的##起到把前面多余的","去掉的作用,否则会编译出错, 你可以试试。可参考:#define qprint(...) printf(__VA_ARGS__),其中__VA_ARGS__代表...可变参数#define printDebugMsg(moduleName, format, ...) \    printf( "[%s] "format" File:%s, Line:%d\n", moduleName, ##__VA_ARGS__, __FILE__, __LINE__ );printDebugMsg( "TestProgram", "data = %d", data );

  上面也说了,只有支持C99规范的gcc编译器才有VA_ARGS这个宏,如果不是gcc编译器,或者所用的gcc编译器版本不支持VA_ARGS宏怎么办? 可参考下面的代码片段,我们换一种做法,可先将可变参数转换成字符串后,再进行输出即可:

void printDebugMsg( const char* format, …)
{
char buffer[DEBUG_BUFFER_MAX_LENGTH + 1]={0};

va_list arg;va_start (arg, format);vsnprintf(buffer, DEBUG_BUFFER_MAX_LENGTH, format, arg);va_end (arg);printf( "%s", buffer );

}

0 0
原创粉丝点击