按数字移位不同于按变量移位

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)

因此,此程序中可能发生任何事情,包括整个崩溃和燃烧。根据经验,从不 将带符号的变量与按位运算符一起使用。