Can the programmer express the intent that this will not overflow? i.e. is it possible to coerce the Rust compiler to optimize (x*2)/2 to x? "Cheap hardware traps" cannot substitute for such a compile-time optimization.
> C seems pretty hopeless since there is no way to know whether or not the coder intended on overflow or not.
Well this doesn't matter: if signed arithmetic overflows the code is undefined, regardless of intent.
In practice comments can express intent, and unsigned arithmetic can with some finessing produce most codegen. Explicit operators would be a big improvement though.
For example, a for loop from 0-through-N (N:i32) will execute N times in C, but N-or-infinity times in Rust. That small difference of infinity controls how the loop condition is tested, whether it can be turned into a simple counter or not.
Eh, not quite true. If N is a 64-bit or an unsigned integer but your loop index is a signed 32-bit integer, then you will have this behavior. In Rust, the idiomatic for loop will have the index variable always be the same size as the condition variable, which prevents the infinity case from happening. In C, if you have a 64-bit condition but a 32-bit unsigned loop index variable, you get the N-or-infinity case as well.
In other words, if your language is subtly redesigned to make you jump through hoops to do things like have mismatched integer types in for loops, then the need to rely on undefined behavior to reclaim that performance is lessened.
LLVM’s constant folding and canonicalization passes will convert (x * 2) / 2 from
%0 = mul i64 %x, i64 2
%1 = div i64 %0, i64 2
to
%0 = shl i64 %x, i64 1
%1 = shr i64 %0, i64 1
Which constant folding will reduce to just %x.
Rust made the right tradeoff here but it is a tradeoff!
This seems awfully close to implementation-defined behavior to me…I'm surprised to see something like this, which allows for (IMHO) unsafe behavior, from Rust.
https://huonw.github.io/blog/2016/04/myths-and-legends-about...