众所周知,当你尝试使用类型规范不匹配的 printf() 系列函数时,GCC 会发出警告。在我们的代码中,我们有许多以下形式的实用函数:
int zzzprintf(DataType *dt, const char *format, ...) {
va_list args;
va_start(args, format);
int status = vprintf(dt->buf, format, args);
va_end(args);
return status
}
我希望看到的是围绕 zzzprintf() 函数的同一组警告语义,例如,如果您调用:
int64_t id64;
zzzprintf(dt, "Hello, %d\n", id64);
你收到警告:
/tmp/foo.c: In function ‘main’:
/tmp/foo.c:7:20: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int64_t’ {aka ‘long int’} [-Wformat=]
zzzprintf("Hello %d\n", id64);
~^ ~~
%ld
注意:我并不是要求增强 GCC 编译器。我正在寻找某种方式来告诉编译器期望这种行为,通过 #pragma 或类似的东西。我们目前正在使用 gcc-8.4.0,并且无法轻松升级我们的 gcc,因为我们暂时被锁定在 Ubuntu 18.04 上。
GCC 支持函数属性,包括一个用于模拟
printf
-like (或scanf
,strftime
, 或strfmon
) 检查的format
属性。你可以在相应的标头中像这样声明你的函数来使用它:这使得包括该头文件在内的所有源文件使用与之相关的编译器检查来处理参数
printf
。正如顶部的链接所示,至少从 GCC 4.7.2 开始就已经支持此功能,因此您的编译器限制不应该成为问题。
这是ShadowRanger答案的一个小扩展:
我有时会在某些目标平台上使用 GCC 以外的编译器,因此我使用宏来封装功能。
由于我使用 GCC 进行开发,错误检查在我的开发平台上有效,我依靠它来保护我在其他平台上的安全。由于我不再使用任何 32 位平台,生活变得轻松多了。