You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust中整数溢出为何有时触发编译错误有时触发运行时错误?

Rust整数溢出:编译错误与运行时错误的差异原因

场景示例

代码示例1

fn main() {
    let num: u8 = 255;
    let num2: u8 = num + 1;
    println!("{}, {}", num, num2);
}

执行$ cargo build --release时无编译错误,但运行$ cargo run会触发运行时panic:

thread 'main' panicked at 'attempt to add with overflow', src/main.rs:3:20
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace

代码示例2

fn main() {
    let num: u8 = 255;
    let num2: u8 = num + 1;
}

执行$ cargo build --release直接触发编译错误:

$ cargo build --release

error: this arithmetic operation will overflow
 --> src/main.rs:3:20
  |
3 |     let num2: u8 = num + 1;
  |                    ^^^^^^^ attempt to compute `u8::MAX + 1_u8`, which would overflow
  |
  = note: `#[deny(arithmetic_overflow)]` on by default

核心原因

这两种差异是Rust编译期静态检查和运行时动态检查的触发逻辑不同导致的:

  • 编译期检查:只拦截100%确定的溢出
    Rust编译器会在编译阶段做静态分析,只有当它能绝对判定某段整数运算必然会溢出时,才会抛出编译错误(默认开启#[deny(arithmetic_overflow)]规则)。
    示例2中,num是固定的u8最大值255,加1的溢出是编译时就能直接推导的必然结果,所以编译器直接报错拦截。

  • 运行时检查:处理静态分析无法确定的情况
    如果编译器没法通过静态分析判定运算是否一定会溢出,就会把检查逻辑留在程序运行阶段。
    示例1中,因为num2被println语句使用了,编译器会认为这个变量有实际用途,不会把这段运算判定为“无意义的必然溢出代码”,因此编译阶段不会报错。等到程序运行时,溢出实际发生,Rust就会触发panic终止程序。

额外补充:在release模式下,编译器会对无意义的代码做更激进的优化,如果溢出运算的结果完全没被使用(比如示例2),编译器能明确判定这是无效且必然溢出的代码,就直接在编译期报错;但如果结果被使用,编译器无法直接抹除这段逻辑,就只能留到运行时检查。


内容的提问来源于stack exchange,提问作者Junhee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 04:37:23