
I guess calling something "undefined behavior" in C is usually different from when you call something UB in Rust? Can the "undefined behavior" in C affect anything else than the result of the integer computation? I don't think so, but the term "undefined behavior" is a bit vague here.
Also note Rust's reference regarding behavior considered unsafe:
The Rust compiler does not consider the following behaviors unsafe, though a programmer may (should) find them undesirable, unexpected, or erroneous.
Anyway, I'm very surprised that signed integer overflows in C are not defined as always wrapping around. A quick Wikipedia check confirms that, but does anyone have a more authoritative link on (signed) integer overflows being undefined in C?
I'm asking because a friend of mine was thinking the Rust rules on interger overflows (panicking in debug-mode, but wrapping around in release-mode) were somewhat awkward. But it looks like it's C is the language with not-well-defined behavior here while Rust just exhibits different (but well-defined) behavior regarding whether in debug-mode or release-mode.
So do I understand right that in Rust signed integer overflows are defined as overflowing in regard two's complement wrapping or causing a panic in debug mode, while in C signed integer overflows are not well-defined? The Rust reference book regarding integer overflow gives only an example with u8 but talks about "two's complement wrapping".
When you’re compiling in release mode with the --release flag, Rust does not include checks for integer overflow that cause panics. Instead, if overflow occurs, Rust performs two’s complement wrapping. In short, values greater than the maximum value the type can hold “wrap around” to the minimum of the values the type can hold. In the case of a u8, the value 256 becomes 0, the value 257 becomes 1, and so on. The program won’t panic, but the variable will have a value that probably isn’t what you were expecting it to have. Relying on integer overflow’s wrapping behavior is considered an error.
Isn't two's complement wrapping only applicable in case of signed numbers? How would the wrapping be called for unsigned numbers? Modular arithmetic? Does the reference need to be updated as in saying:
Instead, if overflow occurs, Rust performs two’s complement wrapping (add this: in case of signed integers and modular arithmetic in case of unsigned integers.)