仅设置符号位的二进制补码整数应当是陷阱表示

把最低的二进制补码整数值(仅符号位为 1 的模式,例如 `INT_MIN`)当作陷阱或类似 NaN 的哨兵,可能会让整数溢出和可选整数更安全、更容易处理,但这会破坏现有代码,并且需要硬件或编译器支持。评论者在对称范围和内建“缺失”值的吸引力,与性能、FFI 互操作性,以及几十年来假设简单回绕算术的软件现实之间进行权衡。许多人认为,更好的工具(sanitizer、显式大整数,或带保留“niche”值的新整数类型)比在 C、C++ 和常见 ISA 中重新定义核心整数语义更可取。

提议与动机

  • 讨论的核心是把“全符号位”的二进制补码值(例如 INT_MIN)设为特殊情况:
    • 要么作为陷阱表示(使用它会导致故障/异常)。
    • 要么作为类似 NaN 的哨兵值,用于表示“缺失”/无效整数。
  • 讨论到的动机:
    • 对称的整数范围(−N..+N,而不是 −N−1..+N)。
    • 使用这种位模式来更便宜地表示 optional<int> / 可空整数。
    • 消除 C 中像 abs(INT_MIN) 溢出这样的边角情况。

硬件、性能与实现

  • 许多人认为这只有在硬件支持下才真正有意义;在每次操作后都由软件检查被认为对低级语言来说代价过高。
  • 也有人指出,动态语言或高级语言(Python、Lisp、Swift、R)本来就已经在承担类似成本(大整数、边界检查、哨兵值)。
  • DSP 和某些 ISA 支持替代的算术模式(饱和算术、溢出标志),也可以加以利用。

正确性、UB 与语言语义

  • 围绕 C/C++ 有符号溢出是未定义行为展开了激烈争论:
    • 有些人希望把回绕(-fwrapv)或陷阱(-ftrapv)作为默认行为。
    • 也有人强调,依赖 UB 做优化已经造成了真实的安全漏洞和难以调试的行为。
  • 区分了两种概念:
    • 陷阱 表示(在 C 中,仅仅读取/写入它就是 UB)。
    • 类似 NaN 的值,具有定义明确的传播语义。
  • 有几条评论指出,把这种机制改造进 C 会破坏现有、当前正确的代码以及 FFI 预期。

替代方案:大整数、饱和、哨兵

  • 讨论的替代方案包括:
    • 默认使用任意精度整数(Lisp、Scheme、Python)。
    • 范围/区间类型,用越界值编码为“缺失”。
    • 饱和算术指令或库操作。
    • 语言或库层面的特定类型(非零、63 位整数、Rust 的 “niche” 优化、OCaml 的带标签整数、R 的 NA 整数)。

安全性 vs 可用性

  • 有些人更倾向于在溢出时崩溃/触发陷阱,以避免静默的数据损坏。
  • 另一些人,尤其是在安全关键或任务关键领域,更优先在值错误时继续运行,而不是让进程死亡。
  • 结论是:理想行为高度依赖具体领域;单一的硬件或语言默认设置无法满足所有使用场景。