有没有什么方法可以让gcc或clang在printf()格式说明符的有符号和无符号变量不匹配时生成警告?我知道使用-Wformat,但是它只在数据类型的大小不正确时报告警告。如果只是符号不正确,它不会生成警告。例如,以下代码不会生成警告,即使将unsigned int打印为signed时不匹配:
-Wformat
uint32_t x = UINT_MAX; printf("%d", x);
这将打印出-1。这似乎是一个有用的警告,但我还没有找到任何方法来启用它。
wz1wpwve1#
用途:-Wformat沿着-Wformat-signedness(必须存在-W格式)。后一个警告选项将在参数的printf说明符符号不正确时发出警告。gcc 6.2将生成以下警告:* 警告:格式“%d”需要类型为“int”的参数,但参数2的类型为“uint32_t {aka unsigned int}”[-Wformat=]*uint32_t x = UINT_MAX;也应该是uint32_t x = UINT32_MAX;
-Wformat-signedness
uint32_t x = UINT_MAX;
uint32_t x = UINT32_MAX;
pqwbnv8z2#
当用户2501正确回答时,-Wformat将启用不正确签名的警告。但如果将"%u"用于uint32_t,则不需要这样做,当您将目标更改为sizeof(int)<sizeof(uint32_t)的系统时,这是不正确的。uint32_t的正确格式说明符是"%"PRIu32、"%"PRIx32、"%"PRIX32和"%"PRIo32,带有零个或多个可选标志。但是,这是扩展为字符串的宏。在具有32位int的系统上,"%"PRIu32"可以扩展为"%""u"。在另一个系统上,int可能只有16位长,而"%"PRIu32"扩展为"%""lu"。在预处理器之后,编译器不知道你是手工写的格式说明符还是使用了缩进的宏。所以编译器不会在32位系统上生成使用"%u"而不是"%"PRIu32"的警告,但是当您将目标体系结构更改为具有较小int的体系结构时,它会发生,并且当您忽略此警告时,此系统上会出现UB。
"%u"
uint32_t
sizeof(int)<sizeof(uint32_t)
"%"PRIu32
"%"PRIx32
"%"PRIX32
"%"PRIo32
int
"%"PRIu32"
"%""u"
"%""lu"
2条答案
按热度按时间wz1wpwve1#
用途:
-Wformat
沿着-Wformat-signedness
(必须存在-W格式)。后一个警告选项将在参数的printf说明符符号不正确时发出警告。
gcc 6.2将生成以下警告:* 警告:格式“%d”需要类型为“int”的参数,但参数2的类型为“uint32_t {aka unsigned int}”[-Wformat=]*
uint32_t x = UINT_MAX;
也应该是uint32_t x = UINT32_MAX;
pqwbnv8z2#
当用户2501正确回答时,
-Wformat
将启用不正确签名的警告。但如果将"%u"
用于uint32_t
,则不需要这样做,当您将目标更改为sizeof(int)<sizeof(uint32_t)
的系统时,这是不正确的。uint32_t
的正确格式说明符是"%"PRIu32
、"%"PRIx32
、"%"PRIX32
和"%"PRIo32
,带有零个或多个可选标志。但是,这是扩展为字符串的宏。在具有32位int
的系统上,"%"PRIu32"
可以扩展为"%""u"
。在另一个系统上,int
可能只有16位长,而"%"PRIu32"
扩展为"%""lu"
。在预处理器之后,编译器不知道你是手工写的格式说明符还是使用了缩进的宏。所以编译器不会在32位系统上生成使用"%u"
而不是"%"PRIu32"
的警告,但是当您将目标体系结构更改为具有较小int
的体系结构时,它会发生,并且当您忽略此警告时,此系统上会出现UB。