"Integer constant is so large that it is unsigned" 编译器警告理由

"Integer constant is so large that it is unsigned" compiler warning rationale

以下C/C++代码:

    long long foo = -9223372036854775808LL; // -2^63

编译 (g++) 时出现警告

integer constant is so large that it is unsigned.

clang++ 给出了类似的警告。

感谢这个错误报告:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52661。我现在明白为什么 GCC 会发出这个警告了。不幸的是,对错误报告的回应并没有很好地解释这种行为的原因。

问题:

这与整数常量类型的定义方式有关。

首先,如gcc错误报告中所述,-9223372036854775808LL实际上是两个标记:一元运算符-和整数常量9223372036854775808LL。所以警告只适用于后者。

C standard 的第 6.4.4.1p5 节指出:

The type of an integer constant is the first of the corresponding list in which its value can be represented.

基于此,没有后缀的十进制整数常量将根据值具有 intlonglong long 类型。这些都是有符号的类型。因此任何小到适合 8 位或 16 位类型的值仍然具有 int 类型,而对于 32 位有符号整数来说太大的值将具有 longlong long 类型,具体取决于关于该系统上类型的大小。后缀为LL的常量也是如此,但只尝试了long long类型。

出现警告是因为您使用的值不在上述类型列表中。任何较小的值都会导致该值具有带符号类型,这意味着不会转换为无符号类型。

正如 bug 报告中或多或少有些困惑的人所说,整数常量 9223372036854775808LL 太大而无法放入 long long.

对于十进制常量,标准在 6.4.4.1 中有一个列表(参见 ),描述了编译器将尝试赋予整数常量的类型。在这种情况下,类型的唯一有效选项是 (signed) long long 并且它不适合那里。然后 table 下的 §6 开始:

If an integer constant cannot be represented by any type in its list, it may have an extended integer type, if the extended integer type can represent its value. /--/
If the list contains both signed and unsigned types, the extended integer type may be signed or unsigned.

扩展整数类型在标准中是一个模糊但正式的术语。在这种情况下,编译器显然会尝试将常量压缩到适合的 unsigned long long “扩展整数类型”中。这不是真正保证的行为,而是实现定义的。

然后将一元运算符 - 应用于产生警告的 unsigned long long

这就是limits.h等库头文件喜欢将LLONG_MIN定义为

的原因
#define LLONG_MIN (-9223372036854775807LL - 1)

你可以做类似的事情来避免这个警告。或者更好的是,使用 LLONG_MIN.

Why is no warning given for the equivalent code for a 32/16/8-bit signed integer constant?

常量不限于 8、16 或 32 位。它是第一种适合的类型,十进制 常量可以达到 至少 63 位。

9223372036854775808LL 超出了 OP 的 long long 范围,因为 9223372036854775808 需要 64 位。

- 应用 常量生成之后。

int,long,long long as 32,32,64 位实现上:-2147483648 是类型 long long,而不是 int


GCC and Clang both give this warning, so it is clearly intentional behavior and not just 'to make it easier to parse,' as is suggested in response to the bug report. Why?

无评论。 Link 没有提供信息。最好到这里数据。


Is this behavior mandated by the C/C++ standard? Some other standard?

是的,按照 C 标准。