整数溢出在C++中引发未定义行为,需通过编译期检查(如-fsanitize=undefined)、运行时防护(如std::add_overflow)和编码习惯(如预校验输入、避免无符号减法)协同防范。
整数溢出在C++中不会自动报错,而是产生未定义行为(UB),轻则逻辑错误,重则被利用触发远程代码执行。检测和避免的关键在于:编译期检查 + 运行时防护 + 编码习惯约束。
现代编译器支持内置的整数溢出检查机制,无需修改源码即可捕获大部分常见溢出:
手动检查每个 +、*、- 是否溢出既繁琐又易漏。推荐使用经过验证的安全封装:
bool 表示是否成功,并通过输出参数写入结果#define SAFE_ADD(a, b, res) (__builtin_add_overflow((a), (b), (res)))(GCC/Clang 内建函数)很多溢出其实在逻辑层就可避免,不依赖运行时检查:
size * elem_size 是否超过 SIZE_MAX
size_t 计算数组索引,避免 int 累加后溢出导致负索引size_t i = 0; i-- 会绕成极大值),改用有符号类型或显式边界判断.at() 而非 [],配合 .size() 检查而非手算下标人工审查难以覆盖所有路径,
需工具补位:
clang++ -O2 --analyze)能识别部分溢出模式,尤其配合注解如 __attribute__((warn_unused_result))
--inconclusive --enable=warning,style)可标记可疑表达式,如 a * b > INT_MAX 类比较基本上就这些。溢出不是“会不会发生”的问题,而是“何时被发现”的问题。把编译器警告当错误、把 sanitizer 当日常、把安全算术当默认,比事后修 bug 省力得多。