4 ms·
Rust does have a fix for this: error: this arithmetic operation will overflow --> src/main.rs:2:18 | 2 | let a: u64 = u64::MAX + 1; |
by sshine 4y ago
Rust does have a fix for this:
error: this arithmetic operation will overflow
--> src/main.rs:2:18
|
2 | let a: u64 = u64::MAX + 1;
| ^^^^^^^^^^^^ attempt to compute `u64::MAX + 1_u64`, which would overflow
|
= note: `#[deny(arithmetic_overflow)]` on by default
Rust also allows for overflowing arithmetic (preserving the default to fail):
https://doc.rust-lang.org/std/?search=overflowing https://doc.rust-lang.org/std/?search=overflowing
It's generally less ergonomic, e.g.
let (zero, _did_overflow) = u64::MAX.overflowing_add(1);
- howinteresting 4y agoYou'll get a compile error when rustc can statically prove that it'll overflow (as in your example above). That is generally not possible. The correct answer is what shepmaster said in a sibling comment.
- deathanatos 4y agoEdit: Gah, I'm a bit wrong too. There's the compiler error (this), and the runtime error (what I'm talking about below.) Here's a link to the runtime variant: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=6e1c0a18458154610ba8ac83065ea97c https://play.rust-lang.org/?version=stable&mode=debug&editio... As a sibling notes, currently, this is for debug builds. So, if you change that playground to "Release", you'll see it wrap. (I love this feature, and I wish they had done it in release mode too. The sibling comment has some notes on that, too.) (But, e.g., were `git` written in Rust, presumably the end product would be a release build. Now, you can enable the check there, but that is something you have to do, today.) (But also note, that, in all cases, it's well-defined. Vs. C, where some overflows are UB.)
- hypeatei 4y agoSlightly related, I wonder why the return type for `overflowing_add` isn't `Result<T>` and instead a tuple containing a boolean?
- re 4y agoThere are times when you want to know how much overflow occurred -- think of the way you learn to do multi-digit addition. There is a checked_add that returns an Option<T> if you only care about success/failure.
- sshine 4y agoAn example is efficient prime-field arithmetic: https://cp4space.hatsya.com/2021/09/01/an-efficient-prime-for-number-theoretic-transforms/ https://cp4space.hatsya.com/2021/09/01/an-efficient-prime-fo... > If A happened to be larger than C, and therefore the result of the subtraction underflowed, then we can correct for this by adding p to the result. [...] we can multiply B by 2^32 using a binary shift and a subtraction, and then add it to the result. We might encounter an overflow, but we can correct for that by subtracting p. (Highlighting the parts that relate to reacting to overflow.)
- jcparkyn 4y agoProbably because you'd want to access the value in either case, depending on your application.
- howinteresting 4y agoCould be a `Result<T, T>` which would seem to express the intent better.
- 3836293648 4y agoSometimes, sure. But an overflow doesn't have to be an error, it can be what you're after and you just want to know when it happens.
- howinteresting 4y agoBinary search is similar and the return type there is already Result<usize, usize>: https://doc.rust-lang.org/std/vec/struct.Vec.html#method.binary_search https://doc.rust-lang.org/std/vec/struct.Vec.html#method.bin...