You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++20之前负数左移为未定义行为,右移为何是实现定义?

C++20前有符号整数左移/右移的行为差异解析

负数左移为何是未定义行为?

  • 有符号整数的溢出本身属于未定义行为。对负数执行左移操作时,极易触发溢出:比如补码表示中,最高位是符号位,左移会将符号位挤入更高位(但有符号整数的位数固定),直接超出其表示范围。
  • 无论底层采用补码、反码还是原码,左移负数都可能触发溢出,而溢出后的行为完全不受标准约束——编译器可进行任意优化(如丢弃代码、生成异常结果等),因此标准将其定为未定义行为。

负数右移为何是实现定义而非未定义?

  • 负数右移不会触发溢出:右移是向低位方向移位,数值只会趋近于0(算术右移)或变为正数(逻辑右移),绝不会超出有符号整数的表示范围。
  • 虽然结果依赖底层表示(补码平台通常是算术右移补符号位,原码/反码平台可能是逻辑右移补0),但这种行为是可预测且可被厂商文档明确说明的。程序在特定平台上的行为是确定的,只是跨平台时可能变化。标准将其定为实现定义,既保留了平台灵活性,又避免了未定义行为的完全不可控性。

简言之:左移负数会触及有符号整数溢出这个未定义行为的核心,而右移负数仅存在行为差异但无溢出风险,因此标准给出了不同的行为定位。

内容的提问来源于stack exchange,提问作者user18676624

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 15:22:05