使用 printf 格式说明符生成错误符号警告

问题描述 投票:0回答:2

有没有什么方法可以让 gcc 或 clang 生成警告,以针对带有 printf() 格式说明符的有符号变量与无符号变量不匹配?

我知道使用

-Wformat
,但是如果数据类型的大小不正确,它只会报告警告。如果只是标志不正确,它不会产生警告。

例如,即使将 unsigned int 打印为 signed 不匹配,以下内容也不会生成警告:

uint32_t x = UINT_MAX;
printf("%d", x);

这将打印出-1。

这似乎是一个有用的警告,但我还没有找到任何启用它的方法。

c gcc-warning
2个回答
8
投票

使用:

-Wformat
-Wformat-signedness
(-Wformat必须存在)。

如果参数对 printf 说明符的签名不正确,后一个警告选项将发出警告。

gcc 6.2 将产生此警告:warning: format '%d' expects argument of type 'int', but argument 2 has type 'uint32_t {aka unsigned int}' [-Wformat=]

还有

uint32_t x = UINT_MAX;
应该是
uint32_t x = UINT32_MAX;


1
投票

当用户 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你忽略这个警告。

© www.soinside.com 2019 - 2024. All rights reserved.