当我按位移1<<<<<<<<<< 45

时间:2012-08-31 20:03:04

标签: c bit-manipulation shift

为什么我会得到这么大的int?

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

检查:1858443624

5 个答案:

答案 0 :(得分:8)

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

  

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

Source

答案 1 :(得分:2)

根据C标准

  

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

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

答案 2 :(得分:2)

90?没门。您需要阅读bit-shifting的内容。 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

答案 3 :(得分: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

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

答案 4 :(得分:0)

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

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

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

x.cpp: In function `int main (int, char **)':
x.cpp:7: warning: left shift count >= width of type