右移和有符号整数

新手上路,请多包涵

在我的编译器上,以下伪代码(用二进制替换的值):

 sint32 word = (10000000 00000000 00000000 00000000);
word >>= 16;

产生一个 word 具有如下所示的位域:

 (11111111 11111111 10000000 00000000)

我可以依赖所有平台和 C++ 编译器的这种行为吗?

原文由 Anne Quinn 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 850
2 个回答

从以下链接:

INT34-C。不要将表达式移位负数或大于或等于操作数中存在的位数

不合规代码示例(右移)

E1 >> E2 的结果是 E1 右移 E2 位位置。如果 E1 具有无符号类型或 E1 具有有符号类型和非负值,则结果的值是 E1 / 2 E2的商的整数部分。如果 E1 具有带符号类型和负值,则结果值是实现定义的,并且可以是算术(有符号)移位:

算术(有符号)移位

或逻辑(无符号)移位:

逻辑(无符号)移位

这个不兼容的代码示例无法测试右操作数是否大于或等于提升的左操作数的宽度,从而允许未定义的行为。

 unsigned int ui1;
unsigned int ui2;
unsigned int uresult;

/* Initialize ui1 and ui2 */

uresult = ui1 >> ui2;

假设右移是作为算术(有符号)移位还是逻辑(无符号)移位实现的,也可能导致漏洞。见建议 INT13-C。仅对无符号操作数使用位运算符

原文由 Andrew Clark 发布,翻译遵循 CC BY-SA 4.0 许可协议

不,你不能依赖这种行为。负量的右移(我假设您的示例正在处理)是实现定义的。

原文由 R. Martinho Fernandes 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题