传递__VA_ARGS__时第一个参数错误

时间:2017-08-17 14:30:07

标签: c macros variadic-functions

我试图将__ 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"

有人知道为什么吗? 感谢

3 个答案:

答案 0 :(得分:3)

这里有两个问题。

首先,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); }

.Skip()

答案 1 :(得分:1)

您的参数顺序错误。您传递给va_start()的那个必须是...之前的那个,因为它用于计算额外参数开始的位置

所以你的功能应该是这样的......

void PrintfError(const char* function, const char* format, ...)
{
    va_list args;
    va_start(args, format);

答案 2 :(得分:0)

来自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)

也不需要##