我有一个班级:
FILE *logFile = fopen("out.log", "w");
class Log {
public:
static void d(const char *message, ...) __attribute__((format (printf, 1, 2)));
}
在源文件中:
void Log::d(const char *message, ...) {
va_list argptr;
va_start(argptr, message);
vprintf(message, argptr);
printf("\n");
fflush(stdout);
if (logFile) {
vfprintf(logFile, message, argptr);
fprintf(logFile, "\n");
fflush(logFile);
}
va_end(argptr);
}
但是当我打电话给例如Log::d("test %d %s %f", 10, "str", 0.1);
时,它会将test 0 @WAíõ 0,000000
打印到文件中。
怎么了?
答案 0 :(得分:1)
问题在于您使用了va_list
argptr
2次。进入vprintf
后进入vfprintf
来电。 va_list
如何使用堆栈实现定义,请参阅here。例如va_list
类型在 Linux x86_64 中实现,如上所述here on SO:
va_list类型
va_list类型是一个数组,其中包含一个结构的单个元素,其中包含实现va_arg宏的必要信息。 va_list类型的定义见图3.34
// Figure 3.34 typedef struct { unsigned int gp_offset; unsigned int fp_offset; void *overflow_arg_area; void *reg_save_area; } va_list[1];
如果您将va_list
传递给第一个vprintf
来电并且该函数返回,va_list
将不再像通话前那样。第二次拨打vfprintf
会收到错误/消耗va_list
"然后
<强>解决方案:强>
如果您的编译器不支持va_copy
,请在va_start
后使用va_start
或使用va_copy
2次。但请记住,每次拨打va_copy
或va_start
都需要拨打va_end
。