为什么我会得到这么大的int?
int ans = 1 << 45;
printf("Check: %d", ans);
return 0;
检查:1858443624
答案 0 :(得分:8)
这是C中未定义的行为。任何事情都可能发生,包括处理器异常之类的东西,或程序其他部分的不可预测的变化(这可能是积极的编译器优化的副作用)。
6.5.7 / 3 [...]如果右操作数的值为负或大于或等于提升的左操作数的宽度,则行为未定义。
答案 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