2 ms·
There's lots of things beyond bounds checks that constitute UB and bounds checks are but 1 small item. Generally Rust avoids the runtime cost of that through a
by vlovich123 3y ago
There's lots of things beyond bounds checks that constitute UB and bounds checks are but 1 small item. Generally Rust avoids the runtime cost of that through a three prong strategy of idiomatic Rust amortizing the cost of a bounds check to 0 (e.g. efficient iterator implementations that don't need bounds checks), eliding the check altogether if the compiler can prove it's duplicate / unneeded for some reason, or providing unsafe Rust as an escape hatch when you absolutely need it. C++ already has something similar via `.at` vs `[]` although the shorter notation being the unsafer but faster option is debatable & likely the thing most people use by default. Explicit annotations are probably the better approach.
It's also got a great ecosystem. I love the assume crate to do these annotations instead of writing unsafe code explicitly:
assume!(unsafe: i < v.len())
Now you've explicitly written an assumption that will cause the compiler to elide the bounds check in release mode but still assert it in debug mode (vs just doing unsafe & using variants that bypass the bounds check).
- aw1621107 3y ago> There's lots of things beyond bounds checks that constitute UB and bounds checks are but 1 small item. Indeed, hence "at a minimum". The type system and choosing to avoid UB when defining some operations helps a lot as well, but those have no direct overhead so there's no runtime cost there. Bounds checks (and overflow checks, if those are ever added to release mode) are just the one thing that have a direct runtime cost when they aren't elided.