c++ - 不正确的 printf 格式说明符编译

标签 c++ gcc

编译这个 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/

相关文章:

python - 在 macOS 上使用 OpenMP 与 Cython 进行编译

c++ - Windows 上 native C++ 应用程序中的自动死代码检测?

c++ - 使用标准 C++ 库堆栈类时堆栈的最大大小是多少?

c++ - 使用 std::strings 和 c 风格的字符串时如何使用模板?

C++ 编译器为 AVX SIMD 代码中从自身减去 +-Infinity 或 +-NaN 的恒定传播给出不同的 NaN 符号

c - 链接描述文件 : insert absolute address of the function to the generated code

C++ 初始化字符串数组

c++ - 返回类型为 T 的函数模板无法编译

c - GCC __attribute__ ((对齐 (8))) 不起作用

c++ - 为什么没有隐式类型转换的警告?