为什么我会得到这么大的整数?
int ans = 1 << 45;
printf("Check: %d", ans);
return 0;
查询:1858443624
为什么我会得到这么大的整数?
int ans = 1 << 45;
printf("Check: %d", ans);
return 0;
查询:1858443624
这是 C 中未定义的行为。任何事情都可能发生,包括处理器异常或程序其他部分中不可预测的变化(这可能是积极的编译器优化的副作用)。
6.5.7/3 [...] 如果右操作数的值为负数或大于或等于提升的左操作数的宽度,则行为未定义。
根据C标准
表达式移动负数或移动量大于或等于提升表达式的宽度 (6.5.7)。
是未定义的行为,因此编译器可以自由地为您在此处提供的代码做任何事情。
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
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
显然,他们随机化了结果:-)
1)正如大家已经说过的,答案是“未定义的行为”。
2)在实践中,几乎我熟悉的每个编译器都会给你“0”。
3)在实践中,大多数自尊的编译器也会给你一个警告:
x.cpp: In function `int main (int, char **)':
x.cpp:7: warning: left shift count >= width of type