【问题标题】:Why does a C compiler not throw a warning when using bitshifting on negative value?为什么 C 编译器在对负值使用位移时不会发出警告?
【发布时间】:2020-06-18 18:28:52
【问题描述】:

为什么我没有收到类似的警告

不允许负数移位

当我使用以下代码时:

#include <stdio.h>

int main (){

    int k = -5;
    unsigned int shift = 2;
    unsigned ans = (k >> shift);

    printf("ans:%u\n",ans);

    return 0;
}

【问题讨论】:

  • 一般而言,编译器无法警告您代码中的所有可能问题。但是,如果您要说出您使用的是什么编译器,那么有人可能会对在这种情况下如何获得警告提出建议。
  • 你在引用谁的“不允许移动负数”?
  • 注意 C 标准并没有说移动负数是“不允许的”;它说结果值是实现定义的。
  • 谁告诉你c编译器或c语言规则应该警告你???

标签: c compiler-construction bit-shift


【解决方案1】:

在 C 中,您可以移动负数。根据编译器将移位解释为算术移位还是逻辑移位,运算结果因系统而异。逻辑移位用 0 填充结果的高位,如果原始数字为负数,则算术移位用 1 填充结果的高位。

结果就是所谓的实现定义,这意味着每个编译器都应该记录它要使用的具体行为。因此,请查看编译器的文档以获取更多详细信息。

这是实现定义的事实可能解释了为什么这里没有警告。负数的移位是完全合法的 C 代码;它只是在所有系统上并不总是意味着同样的事情。

希望这会有所帮助!

【讨论】:

    【解决方案2】:

    不允许移动负数

    这是不正确的。允许对负数进行右移,但结果是实现定义的。

    【讨论】:

      【解决方案3】:

      有符号数的右移由实现定义。大多数现代实现将使用算术移位(和 2 个补数)

      算术移位:

      【讨论】:

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