首页 > 解决方案 > 位移何时会导致未定义的行为

问题描述

我试图找到一个列出所有可能性的好答案(也许只有一个?)。

因此,考虑有符号数和无符号数,哪些是导致 UB 在 C 中进行位移的方法?

标签: c

解决方案


C99 标准对按位移位运算符进行了说明(添加了重点,^用于表示求幂):

§6.5.7.3:对每个操作数执行整数提升。结果的类型是提升的左操作数的类型。如果右操作数的值为负数或大于或等于提升的左操作数的宽度,则行为未定义。
§6.5.7.4:结果E1 << E2E1左移位E2位置;空出的位用零填充。如果E1具有无符号类型,则结果的值为 ,以E1 × 2^E2比结果类型中可表示的最大值大一为模减少。如果E1具有带符号类型和非负值,并且E1 × 2^E2 可以在结果类型中表示,那么这就是结果值;否则,行为未定义。
**§6.5.7.5
:结果E1 >> E2E1右移位E2位置。如果 E1有无符号类型或E1有符号类型和非负值,则结果的值是 的商的整数部分E1 / 2^E2如果E1具有带符号类型和负值,则结果值是实现定义的。

因此,总而言之,如果以下任何一项为真,则行为未定义:

  • 右操作数有符号且为负数,或
  • 右操作数大于或等于左操作数的宽度(提升后),或
  • 左操作数有符号且为负数,或
  • 执行左移,左操作数有符号,结果值不能表示为有符号整数

推荐阅读