1

为什么我会得到这么大的整数?

int ans = 1 << 45;
printf("Check: %d", ans);
return 0;

查询:1858443624

4

5 回答 5

8

这是 C 中未定义的行为。任何事情都可能发生,包括处理器异常或程序其他部分中不可预测的变化(这可能是积极的编译器优化的副作用)。

6.5.7/3 [...] 如果右操作数的值为负数或大于或等于提升的左操作数的宽度,则行为未定义。

来源

于 2012-08-31T20:07:14.957 回答
2

根据C标准

表达式移动负数或移动量大于或等于提升表达式的宽度 (6.5.7)。

是未定义的行为,因此编译器可以自由地为您在此处提供的代码做任何事情。

于 2012-08-31T20:07:38.133 回答
2

90?没门。您需要阅读位移位的作用。1<<45 本质上是2^45. 此外,int只有 31 位(不包括符号位),因此通过尝试移动 45 位,您会导致未定义的行为。

快速示例:

1 << 0  =  1  = 0x01  = 00000001b
1 << 1  =  2  = 0x02  = 00000010b
1 << 2  =  4  = 0x04  = 00000100b
1 << 3  =  8  = 0x08  = 00001000b
于 2012-08-31T20:07:47.193 回答
1

clang(在 X-Code 中使用;AFAIK 他们不再使用 gcc)对此很有趣:

stieber@gatekeeper:~$ clang Test.c -Wno-shift-count-overflow; ./a.out
Check: -1344872728
stieber@gatekeeper:~$ clang Test.c -Wno-shift-count-overflow; ./a.out
Check: -1066238232
stieber@gatekeeper:~$ clang Test.c -Wno-shift-count-overflow; ./a.out
Check: -1373126936
stieber@gatekeeper:~$ clang Test.c -Wno-shift-count-overflow; ./a.out
Check: 779153128

显然,他们随机化了结果:-)

于 2012-08-31T20:14:26.267 回答
0

1)正如大家已经说过的,答案是“未定义的行为”。

2)在实践中,几乎我熟悉的每个编译器都会给你“0”。

3)在实践中,大多数自尊的编译器也会给你一个警告:

x.cpp: In function `int main (int, char **)':
x.cpp:7: warning: left shift count >= width of type
于 2012-08-31T20:11:47.780 回答