“整数常量太大,以致于它是无符号的”编译器警告理由

jez*_*zza 11 c c++ gcc integer clang

以下 C/C++ 代码:

    long long foo = -9223372036854775808LL; // -2^63
Run Code Online (Sandbox Code Playgroud)

编译(g++)并带有警告

整数常量太大,以至于它是无符号的。

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

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

问题:

  • 为什么 32/16/8 位有符号整数常量的等效代码没有给出警告?
  • GCC 和 Clang 都给出了此警告,因此这显然是有意的行为,而不仅仅是“为了使其更易于解析”,正如针对错误报告所建议的那样。为什么?
  • 这种行为是 C/C++ 标准强制要求的吗?还有其他标准吗?

dbu*_*ush 9

这与整数常量的类型如何定义有关。

首先,正如 gcc bug 报告中提到的,-9223372036854775808LL实际上是两个标记:一元-运算符和整数常量9223372036854775808LL。因此该警告仅适用于后者。

C 标准第 6.4.4.1p5 节规定:

整数常量的类型是可以表示其值的相应列表中的第一个。

整型常量表

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

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