45.2.1Compile time detection¶
We define two 16 bit numbers such that their addition will provoke an overflow:
let i: u16 = 0xff00;
let j: u16 = 0x0100;And we add them:
i + j
thread '<unnamed>' (53101) panicked at src/lib.rs:114:40:
attempt to add with overflow
stack backtrace:
0: __rustc::rust_begin_unwind
at /rustc/58cf8f9c35b355199727627d07ae34a4e2846d67/library/std/src/panicking.rs:679:5
1: core::panicking::panic_fmt
at /rustc/58cf8f9c35b355199727627d07ae34a4e2846d67/library/core/src/panicking.rs:80:14
2: core::panicking::panic_const::panic_const_add_overflow
at /rustc/58cf8f9c35b355199727627d07ae34a4e2846d67/library/core/src/panicking.rs:175:17
3: run_user_code_1
4: <evcxr::runtime::Runtime>::run_loop
5: evcxr::runtime::runtime_hook
6: evcxr_jupyter::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
The overflow is detected at compile time.
45.2.2Runtime detection¶
Not all overflow are detectable at compile time. Fortunately, Rust uses a detection mechanism at runtime in debug mode.
The following code compiles without error, but fails at execution:
fn foo(i: u16, j: u16) -> u16 {
i + j
}
foo(0xff00, 0x0100)
thread '<unnamed>' (53101) panicked at src/lib.rs:3:3:
attempt to add with overflow
stack backtrace:
0: __rustc::rust_begin_unwind
at /rustc/58cf8f9c35b355199727627d07ae34a4e2846d67/library/std/src/panicking.rs:679:5
1: core::panicking::panic_fmt
at /rustc/58cf8f9c35b355199727627d07ae34a4e2846d67/library/core/src/panicking.rs:80:14
2: core::panicking::panic_const::panic_const_add_overflow
When confronted with integer overflow (potential or desired), Rust proposes a set of function that allows to enforce the behaviour to apply:
checked_*(): returnNonein case of overflow.strict_*(): panic in case of overflow.unchecked_*(): assume overflow cannot occur (faster), but lead to undefined behaviour when overflow occurs.wrapping_*(): wrap arround at boundaries, avoiding overflow.saturating_*(): saturate at boundaries, avoiding overflow.overflowing_*(): return tuple containing a result and aboolvalue indicating if overflow occurred.
Where * can be:
mul: multiplication.div: division.pow: power.sub: subtraction.add: addition.rem: reminder (modulo,%).shl: shift left (<<).shr: shift right (>>).
In our case, we may choose to enforce saturating of the result:
fn foo(i: u16, j: u16) -> u16 {
i.saturating_add(j)
}
foo(0xff00, 0x0100)65535