c - 位移何时会导致未定义的行为
问题描述
我试图找到一个列出所有可能性的好答案(也许只有一个?)。
因此,考虑有符号数和无符号数,哪些是导致 UB 在 C 中进行位移的方法?
解决方案
C99 标准对按位移位运算符进行了说明(添加了重点,^
用于表示求幂):
§6.5.7.3:对每个操作数执行整数提升。结果的类型是提升的左操作数的类型。如果右操作数的值为负数或大于或等于提升的左操作数的宽度,则行为未定义。
§6.5.7.4:结果E1 << E2
是E1
左移位E2
位置;空出的位用零填充。如果E1
具有无符号类型,则结果的值为 ,以E1 × 2^E2
比结果类型中可表示的最大值大一为模减少。如果E1
具有带符号类型和非负值,并且E1 × 2^E2
可以在结果类型中表示,那么这就是结果值;否则,行为未定义。
**§6.5.7.5:结果E1 >> E2
是E1
右移位E2
位置。如果E1
有无符号类型或E1
有符号类型和非负值,则结果的值是 的商的整数部分E1 / 2^E2
。如果E1
具有带符号类型和负值,则结果值是实现定义的。
因此,总而言之,如果以下任何一项为真,则行为未定义:
- 右操作数有符号且为负数,或
- 右操作数大于或等于左操作数的宽度(提升后),或
- 左操作数有符号且为负数,或
- 执行左移,左操作数有符号,结果值不能表示为有符号整数
推荐阅读
- java - 如何知道数据是否存在于 Firestore 查询快照中?
- api - 使用 Tooling API 在 Salesforce 中创建自定义字段
- c++ - 如何让一个停靠小部件位于屏幕的左边缘,而另一个位于屏幕的右边缘
- reactjs - 未捕获的 DOMException:无法在“历史”上执行“pushState”:无法克隆函数(){[本机代码]}
- vba - VBA Excel在不同的excel文件中查找相同的值
- python - 如何以最短的停机时间将 DynamoDB 表迁移到 Global DynamoDB 表?
- java - KeyListeners 不工作
- python - 如何在python中的块中进行循环
- go - 如何正确使用同步机制从串口读取输入
- node.js - 将代码推送到 git repo 后,npm audit fix 所做的更改是否仍然存在?