代码之家  ›  专栏  ›  技术社区  ›  R2B2

C++中的右移行为

  •  13
  • R2B2  · 技术社区  · 7 年前

    来自cppreference.com:

    对于无符号a和具有非负值的有符号a,值 b . 对于负a,a的值>&燃气轮机; b是实现定义的(在大多数实现中,它执行

    在任何情况下,如果右操作数的值是负数或 行为未定义。


    在我看来,结果应该是0(至少对于无符号/正整数而言)。。。

    unsigned int x = 1;
    cout << (x >> 16 >> 16) << " " << (x >> 32) << endl;
    

    给予: 0 1

    2 回复  |  直到 7 年前
        1
  •  32
  •   aschepler    7 年前

    C++的目标之一是允许快速、高效的代码“接近硬件”。在大多数硬件上,整数右移或左移可以由单个操作码实现。问题是,在移位幅度大于位数的情况下,不同的cpu有不同的行为。

    因此,如果C++为移位操作指定了特定的行为,则在为其操作码行为不符合所有标准要求的CPU生成代码时,编译器需要插入检查和逻辑,以确保结果在所有情况下都是由标准定义的。这种情况几乎需要在所有使用内置移位运算符的情况下发生,除非优化器能够证明这种情况实际上不会发生。增加的检查和逻辑可能会减慢程序的速度。

        2
  •  1
  •   Dmitry Grigoryev    7 年前

    举一个具体的例子,x86将移位计数修剪为5位(6位表示64位移位),而ARM将移位计数修剪为8位。使用当前C++标准,两个CPU的编译器都可以用单个操作码实现移位。

    如果C++标准以特定方式定义移位的结果大于操作数长度,则编译器至少针对CPU家族中的一个(并且可能两者),如果C++所要求的结果与硬件实现不匹配,与您建议的行为类似)必须使用分支来实现每个移位操作,这些分支将产生CPU操作码不需要的结果。