我尝试使用简单的日志记录机制在创建日志时创建错误检查。我观察到,与 printf 相比,可以使用
vfprintf()
,它不会在编译时打印任何警告,传递给格式的参数太多(参见下面的示例)。 (我不希望他们有相同的行为,但我仍然期望类似的行为)。关于这个问题,即使在编译时已知可变参数的数量。有什么方法可以在编译时检查吗?
下面,我准备了一个代码示例,在编译时编译器将打印有关 printf 的警告,并且 vfprintf()
工作正常,没有任何错误。也许第二个可变参数被忽略了?我读了这个人,但找不到任何有用的信息。
#include <stdarg.h>
#include <stdio.h>
void check_printf_usage(char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stdout, fmt, ap);
va_end(ap);
}
int main()
{
int x = 1;
int y = 2;
printf("test nr.1 %i\n", x, y); // works as expected, prints warning
check_printf_usage("test nr.2 %i\n", x, y); // does not print any warning
return 0;
}
这是编译输出+程序输出:
main.c: In function ‘main’:
main.c:21:12: warning: too many arguments for format [-Wformat-extra-args]
21 | printf("test nr.1 %i\n", x, y);
| ^~~~~~~~~~~~~~~~
test nr.1 1
test nr.2 1
printf
和朋友的参数检查是编译器(gcc 和 clang)提供的非常有用的扩展。您可以通过在参数列表和 check_printf_usage
之间用 printf
标记声明来告诉编译器您的函数 __attribute__ ((format(printf, 1, 2)))
需要一个遵循与 ;
相同规则的变量参数列表:
void check_printf_usage(char *fmt, ...) __attribute__ ((format(printf, 1, 2)));