我正在尝试将__VA_ARGS__传递给函数。出于某种原因,第一个参数总是错误的(看起来像一个地址(:
#define PRINTF_ERROR(format, ...) {
PrintfError(format, __FUNCTION__, ##__VA_ARGS__);
}
void PrintfError(const char* format, const char* function, ...)
{
va_list args;
va_start(args, format);
printf("%s(): ", function);
printf(format, args);
va_end(args);
}
例如,尝试打印相同的变量时: "A = 0x20005524 A = 0x00000007">
有人知道为什么吗? 谢谢
这里有两个问题。
首先,va_start
期望当前函数的最后一个命名参数作为其第二个参数。 在这种情况下,那将是function
.
第二个问题是你正在将va_list
传递给printf
。 你应该打电话给vprintf
。
void PrintfError(const char* format, const char* function, ...)
{
va_list args;
va_start(args, function); // pass "function" instead of "format"
printf("%s(): ", function);
vprintf(format, args); // call vprintf
va_end(args);
}
参数的顺序弄错了。您传递给va_start()
的那个必须是...
之前的那个,因为它用于计算额外参数的开始位置
所以你的函数应该看起来像这样...
void PrintfError(const char* function, const char* format, ...)
{
va_list args;
va_start(args, format);
从man va_start
:
void va_start(va_list ap, last);
[...]
描述
va_start()
[...] 参数
last
是变量参数列表之前的最后一个参数的名称,即调用函数知道其类型的最后一个参数。
所以给定
void PrintfError(const char* format, const char* function, ...)
只是改变
va_start(args, format);
要成为
va_start(args, function);
还有这个
printf(format, args);
(这可能是一个错字(应该是
vprintf(format, args);
与您的问题无关,在这里
#define PRINTF_ERROR(format, ...) {
PrintfError(format, __FUNCTION__, ##__VA_ARGS__);
}
花括号只是确保安全的方法的一半。
最好做
#define PRINTF_ERROR(format, ...) do {
PrintfError(format, __FUNCTION__, __VA_ARGS__);
} while (0)
也不需要##
.