按数字移位不同于按变量移位
Shifting by a number is different than shifting by a variable
我有以下c代码:
int foo = 0;
printf("output1: %08x\n", (~0x0) << (~0));
printf("output2: %08x", (~0x0) << (~foo));
打印出:
output1: ffffffff
output2: 80000000
为什么移动相同的数字会产生不同的结果?
有些编译器可能会告诉你原因:
warning: shift count is negative [-Wshift-count-negative]
printf("output1: %08x\n", (~0x0) << (~0));
^ ~~~~
整数是有符号的,它们的补码可能会产生负值,负数的移位是未定义的。
例如在我的机器上它产生:
output1: e785ba48
output2: 80000000
基本上,您的代码段是未定义行为的狂欢。
0x0
字面值和类型 int
的变量是 有符号的 ,这意味着它们可以获得负值。 ~0
始终为负值。
- 左移带负值的有符号整数会调用未定义的行为。 (6.5.7/4)
- 尝试移动比左操作数中的空间更多的位置会调用未定义的行为。 (6.5.7/3)
- 尝试移动负数位会引发未定义的行为。 (6.5.7/3)
因此,此程序中可能发生任何事情,包括整个崩溃和燃烧。根据经验,从不 将带符号的变量与按位运算符一起使用。
我有以下c代码:
int foo = 0;
printf("output1: %08x\n", (~0x0) << (~0));
printf("output2: %08x", (~0x0) << (~foo));
打印出:
output1: ffffffff
output2: 80000000
为什么移动相同的数字会产生不同的结果?
有些编译器可能会告诉你原因:
warning: shift count is negative [-Wshift-count-negative]
printf("output1: %08x\n", (~0x0) << (~0));
^ ~~~~
整数是有符号的,它们的补码可能会产生负值,负数的移位是未定义的。
例如在我的机器上它产生:
output1: e785ba48
output2: 80000000
基本上,您的代码段是未定义行为的狂欢。
0x0
字面值和类型int
的变量是 有符号的 ,这意味着它们可以获得负值。~0
始终为负值。- 左移带负值的有符号整数会调用未定义的行为。 (6.5.7/4)
- 尝试移动比左操作数中的空间更多的位置会调用未定义的行为。 (6.5.7/3)
- 尝试移动负数位会引发未定义的行为。 (6.5.7/3)
因此,此程序中可能发生任何事情,包括整个崩溃和燃烧。根据经验,从不 将带符号的变量与按位运算符一起使用。