If a project is built in release mode, are there any runtime checks enabled by default?

I am curious to know if I ran cargo build --release, does the project still use runtime checks?

If so what runtime checks does it run?

Yes, some run-time checks are always enabled in safe code, including bounds checks on slice indexing. Unsafe code can bypass such bounds checks, at the risk of invoking undefined behavior.

Another example: in safe code, there is no way to turn an arbitrary Vec<u8> into a String without incurring a UTF-8 validity check at run time. But unsafe code can use String::from_utf8_unchecked, at the risk of causing arbitrary bad things to happen when the byte vector is not in fact valid UTF-8.

1 Like

To put it simply: everything marked with #[cfg(debug_assertions)] will be removed in release build, everything else stays here.

1 Like

When reading documentation, if there's a note about panics (example), that indicates a run-time check (that isn't explicit in the API, e.g. returning a Result).

Although bounds checks are logically always run in release mode, they will often not be physically run as LLVM is good at optimizing them out. But don't rely on the optimizer too much :slight_smile:.

1 Like

Integer overflow panics in debug mode but wraps in release mode.

I'm not aware of any other "runtime checks" that are specifically affected by --release.

debug_assert! is disabled in release mode.

Integer division is always checked for divide-by-0 and signed overflow (MIN / -1), as these would have undefined behavior in LLVM. Optimization may still prune those checks if the values are known safe at compile time.