c++中如何判断整数溢出_c++检查加减法是否溢出的安全方法【详解】
发布时间 - 2026-01-22 00:00:00 点击率:次C++23中推荐使用std::add_overflow和std::sub_overflow进行安全加减,语义清晰、无副作用、支持所有整型;若不支持C++23,可用GCC/Clang的__builtin_add_overflow等内置函数;手动检查易出错,需运算前判断且注意类型提升与符号边界。
用 std::add_overflow 和 std::sub_overflow 做安全加减(C++23)
这是目前最直接、标准且无副作用的方案,但仅限 C++23 起可用。它不依赖编译器内置函数或手动位运算,语义清晰,返回 bool 表示是否溢出,并通过输出参数写入结果。
- 必须包含
- 函数签名是
std::add_overflow(a, b, &result),返回true表示溢出,此时result值未定义 - 支持所有有符号/无符号整型,但两个操作数类型需相同,且
result类型必须匹配 - 不改变原值,不引发未定义行为,比手写条件判断更可靠
int a = INT_MAX;
int b = 1;
int result;
if (std::add_overflow(a, b, &result)) {
// 溢出处理:例如抛异常、返回错误码、截断等
} else {
// result == INT_MIN(补码下溢出结果),但这是由函数保证的合法值,非未定义行为
}用编译器内置函数 __builtin_add_overflow(GCC/Clang)
在 C++23 不可用的项目中,这是最常用、高效且被广泛验证的方式。它本质是编译器生成的单条带进位指令检查,零运行时开销。
- 仅 GCC 5+ / Clang 3.4+ 支持,MSVC 不支持(需换用
_addcarry_u32等内联汇编或SafeInt库) - 三个参数:
__builtin_add_overflow(a, b, &result),语义与std::add_overflow一致 - 注意:
a、b、result类型必须完全一致(如全为int),否则编译失败或行为未定义 - 不能用于浮点数,也不能用于类类型;对
char、short会先整型提升,需显式转成int*接收结果
long x = LONG_MAX;
long y = 1L;
long sum;
if (__builtin_add_overflow(x, y, &sum)) {
// 处理溢出
}手动检查加法溢出的边界条件(可移植但易错)
对有符号整数,不能只看结果值——因为溢出后行为是未定义的,任何基于 a + b 的比较都可能被编译器优化掉。正确做法是**在运算前判断**。
- 对于
int加法:a > 0 && b > 0 && a > INT_MAX - b表示正溢出;a 表示负溢出 - 无符号加法更简单:
a + b (利用模运算特性),但前提是a、b是无符号类型,否则隐式转换可能掩盖问题 - 常见错误:写成
if (a + b > INT_MAX)—— 这段代码本身触发未定义行为,编译器可能直接删掉整个分支 - 模板封装时要注意类型推导:用
std::numeric_limits替代硬编码常量,但需确保::max() T是整型且非bool
减法和乘法的溢出检查要点
减法可统一转为加法检查(a - b → a + (-b)),但要注意 INT_MIN - (-1) 这类情况:对有符号数,-INT_MIN 本身溢出,所以不能直接算 -b 再传给加法检查函数。
- 推荐仍用
std::sub_overflow或__builtin_sub_overflow,它们内部已处理该 corner case - 乘法没有标准库函数(C++23 也未加入),
__builtin_mul_overflow是 GCC/Clang 提供的对应版本,用法一致 - 若只能手写乘法检查,需分四象限讨论符号,并用除法反向验证(如
b != 0 && a > INT_MAX / b),但要小心除零和舍入误差 - 所有检查都应在同一类型宽度下进行,避免中间计算因类型提升引入新溢出(例如
in结果应存入
t8_t * int8_t
int16_t再判断)
实际工程中,最容易被忽略的是:溢出检查本身不能成为性能瓶颈,也不应掩盖真正的逻辑错误。比如在循环计数器中频繁调用检查函数,不如改用更大类型(int64_t)或静态断言约束输入范围。而一旦选择检查,就必须覆盖所有路径——尤其是混合类型运算、模板实例化、以及从用户输入直接参与算术的边界点。
# 编码
# c++
# 性能瓶颈
# overflow
# 标准库
# 隐式转换
# 常量
# if
# 封装
# 整型
# bool
# char
# int
# 循环
# 输出参数
# 这是
# 但要
# 加减
# 的是
# 尤其是
# 是由
# 更大
# 推荐使用
# 这段
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
三星、SK海力士获美批准:可向中国出口芯片制造设备
Javascript中的事件循环是如何工作的_如何利用Javascript事件循环优化异步代码?
微信小程序制作网站有哪些,微信小程序需要做网站吗?
如何在沈阳梯子盘古建站优化SEO排名与功能模块?
Laravel怎么进行数据库事务处理_Laravel DB Facade事务操作确保数据一致性
javascript中的try catch异常捕获机制用法分析
韩国代理服务器如何选?解析IP设置技巧与跨境访问优化指南
EditPlus中的正则表达式实战(5)
桂林网站制作公司有哪些,桂林马拉松怎么报名?
北京网站制作的公司有哪些,北京白云观官方网站?
如何基于云服务器快速搭建网站及云盘系统?
linux top下的 minerd 木马清除方法
如何在IIS中新建站点并解决端口绑定冲突?
济南网站建设制作公司,室内设计网站一般都有哪些功能?
Laravel的Blade指令怎么自定义_创建你自己的Laravel Blade Directives
Laravel中间件起什么作用_Laravel Middleware请求生命周期与自定义详解
大连 网站制作,大连天途有线官网?
如何快速生成橙子建站落地页链接?
Laravel如何安装Breeze扩展包_Laravel用户注册登录功能快速实现【流程】
Laravel如何实现用户角色和权限系统_Laravel角色权限管理机制
Laravel如何记录自定义日志?(Log频道配置)
Android利用动画实现背景逐渐变暗
标题:Vue + Vuex + JWT 身份认证的正确实践与常见误区解析
HTML5段落标签p和br怎么选_文本排版常用标签对比【解答】
iOS验证手机号的正则表达式
Python高阶函数应用_函数作为参数说明【指导】
如何使用 jQuery 正确渲染 Instagram 风格的标签列表
胶州企业网站制作公司,青岛石头网络科技有限公司怎么样?
长沙企业网站制作哪家好,长沙水业集团官方网站?
Python图片处理进阶教程_Pillow滤镜与图像增强
Chrome浏览器标签页分组怎么用_谷歌浏览器整理标签页技巧【效率】
Laravel如何实现用户密码重置功能?(完整流程代码)
潮流网站制作头像软件下载,适合母子的网名有哪些?
如何快速搭建二级域名独立网站?
1688铺货到淘宝怎么操作 1688一键铺货到自己店铺详细步骤
JavaScript实现Fly Bird小游戏
Laravel如何发送邮件_Laravel Mailables构建与发送邮件的简明教程
Win11怎么关闭资讯和兴趣_Windows11任务栏设置隐藏小组件
Laravel怎么进行数据库回滚_Laravel Migration数据库版本控制与回滚操作
javascript中的数组方法有哪些_如何利用数组方法简化数据处理
装修招标网站设计制作流程,装修招标流程?
Laravel Seeder怎么填充数据_Laravel数据库填充器的使用方法与技巧
Laravel辅助函数有哪些_Laravel Helpers常用助手函数大全
三星网站视频制作教程下载,三星w23网页如何全屏?
Laravel如何使用Guzzle调用外部接口_Laravel发起HTTP请求与JSON数据解析【详解】
Laravel怎么实现验证码功能_Laravel集成验证码库防止机器人注册
Laravel如何实现本地化和多语言支持?(i18n教程)
Win11怎么设置默认图片查看器_Windows11照片应用关联设置
Laravel PHP版本要求一览_Laravel各版本环境要求对照
打造顶配客厅影院,这份100寸电视推荐名单请查收


