有没有办法让gcc或clang用printf()格式说明符生成有符号和无符号变量不匹配的警告?
我知道使用-Wformat
,但是如果数据类型的大小不正确,则仅报告警告。如果只有标志不正确,它不会生成警告。
例如,即使将unsigned int打印为signed,也不会生成警告:
uint32_t x = UINT_MAX;
printf("%d", x);
这将打印出-1。
这似乎是一个有用的警告,但我没有找到任何方法来启用它。
答案 0 :(得分:5)
使用:-Wformat
和-Wformat-signedness
(必须存在-Wformat)。
如果参数的printf说明符的签名不正确,后一个警告选项将发出警告。
gcc 6.2将产生此警告:警告:格式'%d'需要类型为'int'的参数,但参数2的类型为'uint32_t {aka unsigned int}'[ - Wformat =]
同样uint32_t x = UINT_MAX;
应为uint32_t x = UINT32_MAX;
答案 1 :(得分:0)
当用户2501正确回答时,-Wformat
将启用针对错误手势的警告。但是,对于将"%u"
用于uint32_t
并不需要这样做,当将目标更改为sizeof(int)<sizeof(uint32_t)
的系统时,这是不正确的。
uint32_t
的正确格式说明符是"%"PRIu32
,"%"PRIx32
,"%"PRIX32
和"%"PRIo32
,带有零个或多个可选标志。但是,这是扩展为字符串的宏。在具有32位int
的系统上,"%"PRIu32"
可以扩展为"%""d"
。在另一个系统上,int
可能只有16位长,并且"%"PRIu32"
扩展为"%""lu"
。在预处理程序之后,编译器不知道您是手动编写格式说明符还是使用缩进宏。因此,编译器不会在使用"%u"
而不是"%"PRIu32"
的32位系统上生成警告,但是当您将目标体系结构更改为较小的int
时,它将生成警告。当您忽略此警告时,请在该系统上安装UB。