【问题标题】:bitwise shift operator seems to wrap?按位移位运算符似乎换行了?
【发布时间】:2019-06-05 17:50:12
【问题描述】:

这是 C 文件中的 Windows 7 32 位 Visual Studio 2017。

int i = 65536;

正如所料,

i >> 0 = 65536
i >> 1 = 32768
  :
  :
i >> 16 = 1
i >> 17 to 31 = 0.

i >> 32 又是神奇的 65536。这怎么合法?

ISO/IEC 9899:TC2 规定如下,我认为 C++ 规范是相同的?

E1 >> E2 的结果是 E1 右移 E2 位位置。 如果 E1 有 一个无符号类型,或者如果 E1 有一个有符号类型和一个非负值, 结果的值是 E1 / 商的整数部分 2^E2. 如果 E1 有带符号类型和负值,则结果值 是实现定义的。

【问题讨论】:

  • 标准中的相关引用应该是关于移位超过左侧操作数的位数的引用。
  • 那里没有什么神奇之处,在其他一些语言中,这种行为甚至是强制

标签: c bitwise-operators bit-shift


【解决方案1】:

6.5.7p3

...如果右操作数的值为负数或大于 或等于提升的左操作数的宽度,行为是 未定义

使用 clang、gcc 和 icc,如果您尝试移动一个大于或等于移动值宽度的常量,您将 get a warning,您甚至不需要任何额外的命令行标志.

【讨论】:

  • 好吧,那么,这是一个可怕的规范,但是,要对值是什么(我引用的)做出不合格的陈述,然后在另一段中进行限定。我想知道,为什么他们不只是列出情况和结果的表格。
  • @SwissFrank (或一个)原因是因为不同的 CPU 具有不同的行为,例如,在 x86-32 位上仅使用移位计数的最后 5 位。这意味着如果要独立于平台实现,则需要一些额外的比较/分支/屏蔽。由于 C(和 C++)力求成为一种零开销的语言,因此类似这样的事情是未定义的(或已定义的实现)。
猜你喜欢
  • 1970-01-01
  • 2010-10-02
  • 2013-01-25
  • 2011-03-26
  • 2019-07-26
  • 2012-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多