1

我有以下c代码:

int foo = 0;
printf("output1: %08x\n", (~0x0) << (~0));
printf("output2: %08x", (~0x0) << (~foo));

打印出来:

output1: ffffffff
output2: 80000000

为什么移动相同的数字会产生不同的结果?

4

2 回答 2

3

基本上,您的片段是未定义行为的狂欢。

  • 0x0文字以及类型的变量int都是有符号的,这意味着它们可以得到负值。~0始终为负值。
  • 用负值左移带符号的 int 会调用未定义的行为。(6.5.7/4)
  • 试图移动比左操作数中的空间更多的位置会调用未定义的行为。(6.5.7/3)
  • 尝试移动负数的位会调用未定义的行为。(6.5.7/3)

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

于 2018-02-08T07:42:22.917 回答
2

一些编译器可能会告诉你原因:

warning: shift count is negative [-Wshift-count-negative]
printf("output1: %08x\n", (~0x0) << (~0));
                                 ^  ~~~~

整数是有符号的,对它们进行补码可能会产生负值,并且负数移位是未定义的。

例如在我的机器上它产生:

output1: e785ba48
output2: 80000000  
于 2018-02-08T07:34:18.937 回答