1
0
mirror of https://github.com/google/comprehensive-rust.git synced 2025-07-02 13:14:30 +02:00
Files
comprehensive-rust/src/types-and-values/arithmetic.md
Martin Geisler c45b291851 Clarify what "undefined behavior" means in arithmetic.md (#2139)
Undefined behavior does not just mean that the behavior can be different
on different platforms. It is much worse than that: the runtime behavior
can be completely nonsensical since the whole program has undefined
behavior.

The compiler will optimizer as if there is no undefined behavior and
will can lead to strange situations as the compiler concludes that
things like `a > a + 1000` can never be reached if `a` is a signed 8-bit
value (since reaching it would trigger undefined behavior).
2024-06-10 10:18:25 -04:00

1.1 KiB

minutes
minutes
3

Arithmetic

fn interproduct(a: i32, b: i32, c: i32) -> i32 {
    return a * b + b * c + c * a;
}

fn main() {
    println!("result: {}", interproduct(120, 100, 248));
}

This is the first time we've seen a function other than main, but the meaning should be clear: it takes three integers, and returns an integer. Functions will be covered in more detail later.

Arithmetic is very similar to other languages, with similar precedence.

What about integer overflow? In C and C++ overflow of signed integers is actually undefined, and might do unknown things at runtime. In Rust, it's defined.

Change the i32's to i16 to see an integer overflow, which panics (checked) in a debug build and wraps in a release build. There are other options, such as overflowing, saturating, and carrying. These are accessed with method syntax, e.g., (a * b).saturating_add(b * c).saturating_add(c * a).

In fact, the compiler will detect overflow of constant expressions, which is why the example requires a separate function.