您现在的位置是:烟消火灭网 > 百科
变量溢出
烟消火灭网2026-10-17 07:42:19【百科】3人已围观
简介去年冬天,我在一个老旧的嵌入式项目里踩了个坑。设备运行三天后必死机,日志里找不到任何异常。最后定位到一行代码:一个uint8_t类型的计数器,每秒钟加一。255秒后,它溢出归零。程序逻辑依赖这个计数器
去年冬天,变量溢出我在一个老旧的变量溢出嵌入式项目里踩了个坑。设备运行三天后必死机,变量溢出日志里找不到任何异常。变量溢出最后定位到一行代码:一个uint8_t类型的变量溢出计数器,每秒钟加一。变量溢出255秒后,变量溢出它溢出归零。变量溢出程序逻辑依赖这个计数器判断超时,变量溢出结果每隔四分钟就误判一次,变量溢出把正常流程打断。变量溢出
变量溢出这事,变量溢出说大不大,变量溢出说小能要命。变量溢出它不像空指针那样立刻崩溃给你看,变量溢出更像慢性病——平时没事,特定条件下突然发作。你盯着代码看半天,逻辑都对,可它就是错了。
我后来养成了一个习惯:凡是看到循环里的累加变量,先问一句“它最大能装多少”。有次review同事的代码,一个int32_t的毫秒计时器,理论上49天溢出。同事说“设备不可能连续跑49天”。结果客户那边真有一台机器常年不关机,第50天凌晨三点,定时任务全部错乱。修复方案很简单,换成int64_t。但排查花了整整一周,因为没人往那个方向想。
溢出的本质是信息被截断。你给变量分配了8个比特,它就只能表达256种状态。超过这个范围,高位被无声地丢弃。C语言不会报错,Java不会抛异常,Python倒是会自动扩容——所以很多人从Python转到C或Go时,第一次遇到溢出会愣住。语言设计哲学不同,代价也不同。
有意思的是,有些溢出是故意的。哈希函数里经常利用整数溢出来实现模运算,游戏开发里用无符号整数的回绕做环形缓冲区。这时候溢出不是bug,是feature。区别在于:你知不知道它会发生,以及你有没有为它写好边界处理。
真正危险的是隐式类型转换带来的溢出。比如两个int相乘,结果赋给long long。你以为安全了,其实乘法已经在int范围内溢出过了,赋给再大的类型也救不回来。得写成(long long)a * b才行。这种坑,静态分析工具有时候都扫不出来。
我现在写代码,遇到计数器、累加器、时间差计算,条件反射地会想三件事:这个变量最大能到多少?它会不会被减成负数?跨平台时类型宽度一致吗?听起来有点神经质,但比起半夜被叫起来查一个“莫名其妙”的故障,我宁愿平时多花那几秒钟。
变量溢出不会消失。只要计算机还是有限状态的机器,只要人类还在用固定宽度的类型,它就会一直在那里。你能做的,无非是知道它什么时候会来,然后提前把路让开。
很赞哦!(951)
上一篇: 嘉兴工程师申请网站
下一篇: zentao禅道官网







