https://play.rust-lang.org/?version=stable&mode=debug&editio... https://play.rust-lang.org/?version=stable&mode=debug&editio...
By default, they're on during debug mode and off in release mode.
[0]: https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=847dc401e16fdff14ecf3724a3b15a93
[1]: https://doc.rust-lang.org/cargo/reference/profiles.html
https://learn.adacore.com/courses/intro-to-ada/chapters/stro...
And there is an Ada implementation that is part of GCC:
For comparison, Swift uses "+" for checked addition and as a result, majority of developers use checked addition by default. And in Rust due to its poor design choices most developers use wrapping addition even where a checked addition should be used.
[1] https://doc.rust-lang.org/src/alloc/vec/mod.rs.html#2010
Rust developers made a poor choice. They should have made a special function for unchecked addition and have "+" operator always panic on overflow.
Just insist that the programmer prove that overflow can't occur, and reject programs where the programmer couldn't or wouldn't do this.
Your example code is not because it is faster to write, it is because it is impossible for its to overflow on that line.
This line could only overflow after we need to grow the container, so immediately this means the type T isn't a ZST as the Vec for ZSTs doesn't need storage and so it never grows.
Because its not a ZST the maximum capacity in Rust is never bigger than isize::MAX which is an entire binary order of magnitude smaller than usize::MAX, as a result len + 1 can't overflow the unsigned type, so this code is correct as written.
The checks being on in the debug config means your tests and replications of bug reports will catch overflow if they occur. If you are working on some sensitive application where you can't afford logic bugs from overflows but can afford panics/crashes, you can just turn on checks in release mode.
If you are working on a library which is meant to do something sensible on overflow, you can use the wide variety of member functions such as 'wrapping_add' or 'checked_add' to control what happens on overflow regardless of build configuration.
Finally, if your application can't afford to have logic bugs from overflows and also can't panic, you can use kani [0] to prove that overflow never happens.
All in all, it seems to me like Rust supports a wide variety of use cases pretty nicely.
There are also specific methods for doing *erflow-checked arithmetic if you like.
Of course, if you don't trust the standard library, you can turn on overflow checks in release mode too. However, the standard library is well tested and I think most people would appreciate the speed from eliding redundant checks.
[0]: https://doc.rust-lang.org/src/alloc/raw_vec.rs.html#651
[1]: https://doc.rust-lang.org/src/alloc/raw_vec.rs.html#567
Or just because on Intel CPUs it has overhead, we must forget about writing safer code?