C++ 浮点转整型的未定义行为陷阱
来源:kttnr.net — 2026-07-31
📋 概述
C++ 中将浮点数转换为整数时,若截断后的值超出目标整数范围,行为是未定义的。作者指出即便在 -Wall -Wextra 下编译器也不会对此发出警告,且 Microsoft GSL 的 gsl::narrow 对此场景同样存在 UB。不同硬件(x86 的 CVTTSS2SI vs AArch64 的 FCVTZS)会产生不同结果,编译器优化也可能随时改变行为。正确的修复是在转换前做边界检查。
🔑 核心要点
- 浮点到整型转换在值超出目标范围时是未定义行为,即使开启所有警告也不会被检测到。
- Microsoft GSL 的 gsl::narrow 被文档描述为安全的窄化转换,但实际上对 float-to-int 并未做边界检查。
- x86 的 CVTTSS2SI 将所有不可表示值映射为 INT_MIN,而 AArch64 的 FCVTZS 做饱和处理并将 NaN 映射为零——跨平台结果不一致。
- 任何执行中的未定义行为都可能被编译器优化破坏,正如 Ralf Jung 所说:"硬件做了什么"不等于"你的程序做了什么"。
- Clang 和 GCC 的 -fsanitize=float-cast-overflow 可以在运行时检测此类 UB。
💡 金句
你的程序不崩溃会让问题看起来无害。但它不是——任何执行中的未定义行为都是问题。
👍 0
👎 0
← 返回 Lobsters 首页