编译这个 MCVE
#include <stdio.h>
#include <climits>
#include <limits>
int main()
{
unsigned long x = ULONG_MAX;
printf( "1:=%lu - 2:=%lu 3:=%ld\n", std::numeric_limits<size_t>::max(), x, x );
}
有了这些gcc/clang [any version] options -Wall -Werror -pedantic
不会失败。
这是输出:
1:=18446744073709551615 - 2:=18446744073709551615 3:=-1
我预计会出现错误,因为我提供了一个 unsigned int
但格式说明符是 signed int
。
用 PowerPC gcc 4.8 编译它按预期失败:
error: format '%lu' expects argument of type 'long unsigned int', but argument 2 has type 'unsigned int' [-Werror=format=]
我的问题是:
为什么 gcc/clang 编译这些格式说明符?对我来说,我会说 PowerPC gcc 是正确的,因为这是一个严重的符号/未符号问题,错误的格式说明符显示不正确的结果。
最佳答案
根据 GCC(最低版本 5.0)文档,
-Wformat-signedness If -Wformat is specified, also warn if the format string requires an unsigned argument and the argument is signed and vice versa.
此设置不是默认设置,因为标准没有要求。如果您想要超过标准,则需要使用正确的标志。在您的情况下,您正在通过 -Wall 使用 -Wformat 而不是 -Wformat-signedness。请记住,-Wall 不会打开所有警告,它只是一个几乎所有人都同意的子集。
编译器会检查类型安全,因此当您删除长说明符时会收到警告。除此之外,如果数据没有丢失(如从 sign 到 unsigned 或 unsigned 到 sign 或从 int 到 long 的提升,等等),他们可以无所事事。事实上,clang 没有用于符号检查格式的标志 (AFAIK)。
关于c++ - 不正确的 printf 格式说明符编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42314952/