【问题标题】:Shifting by a number is different than shifting by a variable数字移位与变量移位不同
【发布时间】:2018-02-08 07:28:02
【问题描述】:

我有以下c代码:

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

打印出来的:

output1: ffffffff
output2: 80000000

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

【问题讨论】:

  • 您正在移动 signed 值。按签名金额。 IIRC 后者是未定义的行为
  • 两者都是未定义的行为;你得到的结果是任意的。您只能将 0 移动到比类型中的位数少 1 的位置。见C11 §6.7.5 Bitwise shift operators
  • @Someprogrammerdude:有符号的班次并不是一个特别的问题;负移位是,~0 是负数(通常被视为-1)。

标签: c byte-shifting


【解决方案1】:

基本上,您的 sn-p 是一种未定义行为的狂欢。

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

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

【讨论】:

    【解决方案2】:

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

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

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

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

    output1: e785ba48
    output2: 80000000  
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多