4 ms·
In Rust, 3u64 - 4u64 is "error", specifically thread 'main' panicked at 'attempt to subtract with overflow'
by tromp 5y ago
In Rust, 3u64 - 4u64 is "error", specifically
thread 'main' panicked at 'attempt to subtract with overflow'
- Macha 5y agoIt panics _in debug builds_ but wraps in release builds because including the checks in every arithmetic operation is not zero cost.
- masklinn 5y agoThough you can configure your release builds to panic as well. That can be quite useful if you don't expect trivial computations to be a large cost center (and you can always bench to check that assumption). Even more so now that custom profiles have been added to Cargo (yay), you can enable overflow checking in release, and add a `release-unchecked` or whatever.
- tialaramex 5y agoOr, better in many cases, you can write what you meant explicitly in Rust. 3u64.checked_sub(4u64).expect("Overflow"); This allows you to spell out that you don't expect this to overflow, and Rust should panic if it does, regardless of your compiler flags.
- masklinn 5y agoOf course you can do that, but I would say that doing so defensively for every operation is way more verbose and unwieldy than you'd want. Much simpler to just toggle on the relevant flag.
- eyelidlessness 5y agoI think GP was saying you can do that when you expect that the general case doesn’t need to be checked but a specific case does.
- masklinn 5y ago> when you expect that the general case doesn’t need to be checked but a specific case does. But surely that's almost never the case? Few programs actually desire or care for base 2 modular arithmetics, and when they do it tends to be for very specific tasks (usually cryptographic or cryptography-adjacent e.g. hashing, checksumming, ...).
- eyelidlessness 5y ago> But surely that's almost never the case? Which is why it’s not so impractical to make an occasional exception.
- deepsun 5y agoI wish they had "unchecked_sub()" instead, and default "-" would work like checked_sub().
- tialaramex 5y agounchecked_sub() exists in Nightly and so may some day come to stable However, changing - to perform checked_sub() leaves you with an Option, and this makes ordinary arithmetic look pretty clumsy: let x = (a-b).unwrap()-c; The intent is to land more types with intrinsic behaviour. Today only the Wrapping type is provided, so Wrapping<i32> is an i32 that definitely has Wrapping arithmetic and won't panic on overflow, but eventually Saturating<i16> will be possible (e.g. for CD audio PCM samples, saturating arithmetic is correct, if you try to make the loudest possible noise louder it just stays the same) and so will Unchecked<i8> if you really sure that you're doing 8-bit arithmetic that can't overflow and doesn't need Debug checks.