C语言 为什么int e = 3000000000在gcc中不是警告?



考虑以下 C 程序:

#include <stdio.h>
int main(int argc, char *argv[]) {
int a = -5000000000;
int b = -3000000000;
int c = -1000000000;
int d =  1000000000;
int e =  3000000000;
int f =  5000000000;
printf("a = %dn", a);
printf("b = %dn", b);
printf("c = %dn", c);
printf("d = %dn", d);
printf("e = %dn", e);
printf("f = %dn", f);
return 0;
}

还要考虑以下环境输出:

pvz@DESKTOP-OTTHA70:~$ uname -a
Linux DESKTOP-OTTHA70 4.19.104-microsoft-standard #1 SMP Wed Feb 19 06:37:35 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
pvz@DESKTOP-OTTHA70:~$ gcc --version
gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

而这个编译器输出:

pvz@DESKTOP-OTTHA70:~$ gcc -Wall -o overflow overflow.c
overflow.c: In function ‘main’:
overflow.c:4:10: warning: overflow in implicit constant conversion [-Woverflow]
int a = -5000000000;
^
overflow.c:5:10: warning: overflow in implicit constant conversion [-Woverflow]
int b = -3000000000;
^
overflow.c:9:11: warning: overflow in implicit constant conversion [-Woverflow]
int f =  5000000000;
^~~~~~~~~~

而这个程序输出:

pvz@DESKTOP-OTTHA70:~$ ./overflow
a = -705032704
b = 1294967296
c = -1000000000
d = 1000000000
e = -1294967296
f = 705032704

在这台机器上,int 的宽度为 32 位,范围为 -2 31 (-2147483648( 到231- 1(2147483647(。

正如预期的那样,尝试将不适合该范围的值放入变量中会导致警告,并且该值的最高有效位被截断,从而导致整数变量 a、b、e 和 f 中出现意外值。

但是,编译器只警告我们 a、b 和 f,而不是 e

因此,问题是,为什么 gcc 不警告以下行?

int e = 3000000000;

据我所知,如果您尝试将它们塞入 int,那么从231232- 1的值实际上并不是警告。我也怀疑这是一个编译器错误,因为这似乎是很久以前就会发现的东西。这意味着这可能是故意行为。但是为什么?

从问题注释中进行的一些调查中,我们发现这种行为至少可以追溯到 1993 年 10 月 30 日,在 Richard Stallman 提交的提交中,此提交消息:

"(convert_and_check(:不要警告将0xff转换为签名字符等,除非迂腐。">

从SVN:r5944

作者的意图似乎是在对char进行签名的计算机上,较大的十六进制值卡在char中的情况禁止警告。(char可以签名或无符号,具体取决于根据 C 标准的实现。

但在这样做时,它也对任何有符号整数类型的更一般情况以及十进制表示形式进行了此操作,而不仅仅是十六进制或八进制表示。

在我个人看来,这可能是一个错误的特征(我可能只会抑制十六进制或八进制表示的警告(,但这是一个判断,我认为gcc维护者比我更有资格做出。

相关内容

  • 没有找到相关文章

最新更新