C++中异或(xor)运算是否会产生未定义行为(UB)或未指定行为(IB)?
C++ 场景下有符号整数位运算的规则说明
你提到的两个相关问题的讨论均基于C语言规则,C与C在有符号整数位运算的规则上确实存在差异,以下是C标准下的明确规则说明:
本说明所有规则仅适用于C++,与C语言的对应规则不互通,不具备参考性。
1. 基础前提:有符号整数的表示规则
- C++20及更高版本:标准强制要求所有有符号整数采用补码表示,不存在其他实现形式。
- C++20之前的版本:标准允许有符号整数采用补码、反码、原码三种实现形式,具体由编译器决定。
2. 各类位运算的行为定义
按位与&、按位或|、按位异或^
这三类运算均是对操作数的二进制位逐位执行对应逻辑运算:
- C++20及以上版本:所有合法的有符号整数参与这三类运算的结果均有明确定义,可直接基于补码规则推导。
- C++20以下版本:运算结果由实现采用的有符号整数表示方式决定,属于实现定义行为,不属于未定义行为。
按位取反~
对操作数的所有二进制位逐位取反:
- C++20及以上版本:结果明确定义,
~x等价于-x - 1。 - C++20以下版本:结果由实现采用的有符号整数表示方式决定,属于实现定义行为。
左移运算符<<
将操作数的二进制位向左移动指定位数,右侧补0:
- 操作数为负值时,左移运算始终属于未定义行为,不受C++版本影响。
- 操作数为非负值时,如果左移后的结果超出对应有符号整数类型的可表示范围,属于未定义行为;否则结果明确定义,等价于原值乘以2的对应次方。
右移运算符>>
将操作数的二进制位向右移动指定位数:
- 操作数为非负值时,结果明确定义,等价于原值除以2的对应次方向下取整,左侧补0。
- 操作数为负值时,结果属于实现定义行为,绝大多数编译器实现为算术右移(左侧补符号位,等价于除以2的对应次方向下取整),少数实现为逻辑右移(左侧补0),不存在未定义行为。
内容的提问来源于stack exchange,提问作者0dminnimda
相关产品推荐
相关产品推荐

