左移位负移位计数

Ish*_*shq 61 c

这到底发生了什么?

a << -5

显然它没有正确转变.但我正在阅读的这本书指出:

在一台机器上,这个表达式实际上是左移27位

我的问题是; 为什么?什么原因导致27位左移?在使用负移位计数换档时会发生什么?谢谢.

Lun*_*din 73

右侧的负整数是C语言中未定义的行为.

ISO 9899:2011 6.5.7逐位移位运算符:

对每个操作数执行整数提升.结果的类型是提升的左操作数的类型.如果右操作数的值为负或大于或等于提升的左操作数的宽度,则行为未定义.

  • 顺便说一下,如果你的书没有提到这是不明确的行为,你应该考虑另外一本书. (25认同)
  • 根据这本书所说的其他内容,你可以说这正是它所说的(尽管它可能会更清楚)。“在一台机器上发生某事”隐含地意味着它可能不会在其他机器上发生。 (2认同)
  • @CiroSantilli六四事件法轮功许多未定义的行为来自C标准委员会的缺点,而不是一些关于硬件限制的合理理由.但是在这种情况下,我真的没有太大的改进空间:如果标准强制将右操作数提升为无符号类型,你仍然会得到类似`a <<(unsigned int)-5`的东西.意思是"a << 0xFFFFFFFB",上面引用的文字也是UB. (2认同)

Ana*_*and 16

正如其他成员已经回答的那样,它会产生未定义的行为.我想在这里提一下,你引用这本书("在一台机器上")似乎是偏袒的.它没有概括行为.该书也可能已经解释了该行为未按照标准定义.顺便说一句,我刚刚通过"新C标准 - 经济和文化评论"并发现了这一说法:

英特尔奔腾SAL指令(由gcc和Microsoft C++生成以评估左移)仅使用移位量的后五位

这很好地解释了为什么-5的左移可能导致左移27(对于负数的2的补码表示)

  • 我确信OP的书中的"On one machine"句子只是作为一个例子,在说明这是未定义之后.它实际上是一个很好的例子,"未定义"实际上意味着什么,而不仅仅是"干净"突然终止执行程序.如果以这种方式使用,那么给人的印象就是左移27乘以你有权期待的东西. (3认同)

Oli*_*rth 11

行为未定义.

在5位二进制算术中,二进制补码-5具有与无符号+27相同的二进制表示,这可能解释了该特定平台.

  • @ClsForCookies - 在电气层面,它是真实的.关于8没什么特别的. (3认同)