应使用 std::numeric_limits<T>::max() 和 min() 判断越界,避免手写 INT_MAX 等常量导致类型不匹配;加减法前须预防性检查,因溢出是未定义行为。

用 std::numeric_limits 查上限下限,别手写常量
直接靠 INT_MAX 或 INT_MIN 判断越界看似简单,但容易漏掉类型不匹配的问题——比如你传入的是 long long,却用 INT_MAX 比较,编译器不报错,逻辑却早崩了。std::numeric_limits 能绑定具体类型,编译期就锁死范围。
- 对
int:用std::numeric_limits<int>::max()</int>和std::numeric_limits<int>::min()</int> - 对模板函数或泛型代码:用
std::numeric_limits<t>::max()</t>,T 是推导出的实际类型 - 注意包含头文件:
<limits>,不是<climits>
加法前必须检查,而不是加完再判断结果
整数溢出在 C++ 中是未定义行为(UB),一旦发生,程序可能崩溃、返回错误值,甚至被编译器优化掉整个分支。所以不能写 if (a + b > INT_MAX) —— 这行代码本身已触发 UB。
- 正确做法:加法前做预防性检查,例如
a > std::numeric_limits<int>::max() - b</int> - 减法同理:
a ::min() + b(注意符号) - 乘法更危险:需分情况处理正负号,推荐用
std::mul_overflow(C++23)或第三方库如absl::int128做中间计算
std::add_overflow(C++23)能省事,但得确认编译器支持
如果你用的是 GCC 13+、Clang 16+ 或 MSVC 19.35+,且项目允许 C++23,std::add_overflow 是最干净的方案——它把检查和计算合为一步,返回 bool 表示是否溢出,并通过引用参数输出结果。
- 用法示例:
int result; bool overflow = std::add_overflow(a, b, result); - 不支持时别硬上:部分旧版本 libc++ 或 MinGW 可能没实现,编译失败比运行时 UB 更早暴露问题
- 替代方案:自己封装一个 inline 函数,用上面提到的减法预检逻辑,避免重复写一堆条件
隐式转换是越界黑手,尤其在函数调用和容器操作中
很多越界其实不是算术导致的,而是类型自动提升或截断惹的祸。比如把 size_t(通常是 unsigned long)赋给 int,或者用 vector::at(i) 传入负索引——i 是 int,但 at 接收 size_t,负数会转成极大正数,直接越界访问。
立即学习“C++免费学习笔记(深入)”;
- 开启编译警告:
-Wsign-conversion(GCC/Clang)能抓大部分隐式有符号/无符号转换 - 容器索引统一用
size_t或vector::size_type,别混用int - 读取用户输入或外部数据后,立刻做范围校验,别等到参与计算才想起来
事情说清了就结束。越界检查不是“加个 if 就完事”,关键在时机(加之前)、类型(绑定而非硬编码)、以及那些看不见的隐式转换。










