points by crote 4 days ago | 0 comments
The problem is that it silently overflows by default - and a good chunk of the time it is even undefined behavior. Sure, in some situations you as the developer are 100% certain that an overflow is impossible (despite the compiler not being able to prove this and therefore eliminate the checks), but in the vast majority of cases it is a footgun silently waiting to go off.
Rust tries to solve this by having basic addition panic in debug, while silently-but-consistently continuing in production: overflow is considered a bug, but it is at least not a platform-dependent bug.
If overflow is expected, then there's checked_add to detect it and fail in a friendly way, saturating_add / wrapping_add / carrying_add for specific overflow behavior.
Finally, if speed is crucial and overflow is either impossible or you don't care about the outcome whatsoever, there's unchecked_add to explicitly opt-in to a C-like "just do whatever the machine feels like".
You can still do everything you can with C. It it just an explicit choice, rather than an implicit platform-dependent mechanism you might forget about.
Just like for signed integers in C the {integer}::unchecked_add is Undefined Behaviour if overflow occurs. So that's not "whatever the machine feels like" it's much worse.
This is an unsafe function, so you're expected to write a SAFETY rationale for the unsafe call, and that's your opportunity to justify to a future maintainer why you were sure this addition never overflows. If you find yourself struggling to justify that belief it probably means you should not have used this function.
If you're going to write guard code for overflows, and use that to justify the SAFETY claim, why not use the existing functions for that? Clippy will suggest this in many cases because it's less likely you will blow your own foot off.