首页 > 解决方案 > 为什么 C 编译器在为有符号类型分配过高的整数值时不发出警告?

问题描述

(假设是 64 位机器)

例如

int n = 0xFFFFFFFF; //max 32bit unsigned number
printf("%u\n", n);

常规有符号整数(32 位)可以存储的最大正数是0x7FFFFFFF.

在上面的示例中,我将最大无符号整数值分配给常规有符号整数,我没有收到来自 GCC 的警告或错误,并且打印结果没有问题(带有-Wall -Wextra)。

U将或附加L到十六进制常量不会改变任何内容。

这是为什么?

标签: cintegerunsigned-integer

解决方案


0xFFFFFFFF,在unsigned最大值为 2 32 -1 的平台上,将具有unsigned根据标准的“6.4.4.1 整数常量”的类型。

然后我们进行转换:

6.3.1.3 有符号和无符号整数

1 当整数类型的值转换为_Bool以外的其他整数类型时,如果该值可以用新的类型表示,则不变。
2 否则,如果新类型是无符号的,则通过在新类型中可以表示的最大值的基础上反复加减一来转换该值,直到该值在新类型的范围内。60)
3 否则,新类型是有符号的,值不能在其中表示;结果要么是实现定义的,要么是产生实现定义的信号。

因此,结果是实现定义的或引发实现定义的信号。

现在,您使用 format 打印您int的格式%u,这完全不匹配。虽然这严格来说是 UB,但假设您有 2s-complement 并且原始分配使用环绕,您可能会得到原始常量。


推荐阅读