logoalt Hacker News

tialaramextoday at 3:19 PM3 repliesview on HN

In Rust the decision about whether to pay for overflow checks or just wrap (because all modern hardware will just wrap if you don't check and that's cheaper) is a choice you can make when compiling software, by default you get checks except in release builds but you can choose checks everywhere, even in release builds or no checks even in debug.

By definition in Rust it's incorrect to overflow the non-overflowing integer types, and so if you intend say wrapping you should use the explicit wrapping operations such as wrapping_add or the Wrapping<T> types in which the default operators do wrap - but if you turn off checks then it's still safe to be wrong, just as if you'd call the wrapping operations by hand instead of using the non-wrapping operations.

That Dolby overflow code looks awkward enough that I can't imagine writing it in Rust even if the checking was off - but I wasn't there. However the reason it's on Project Zero is that it resulted in a bounds miss, and that Rust would have prevented anyway.


Replies

kllrnohjtoday at 10:02 PM

I love most of what Rust does, but this is something they just got wrong. The + operator should always trap on overflow. Which Rust kinda wanted to do (hence why it does that in debug builds), but then they chickened out about the performance risk for release builds, undermining the entire thing. The result is just weak lip service to "no UB!", since debug and release still have very different behavior

I think Zig has the most interesting approach here with 3 different "+" operators (+ aborts on overflow, +& wraps, and +| saturates) along with addWithOverflow builtin. It'd probably be a challenge for Rust to adopt that at this point, but it'd be a great improvement

codedokodetoday at 4:50 PM

> is a choice you can make when compiling software

That is not a solution because it means the code can behave differently, and expose vulnerability if wrong compilation settings are chosen.

The functions like "wrapping_add" have such a long names so that nobody wants to use them and they make the code ugly. Instead, "+" should be used for addition with exceptions, and something like "wrap+" or "<+>" or "[+]" used for wrapping addition.

That's how people work, they will choose the laziest path (the simplest function name) and this is why you should use "+" for safer, non-wrapping addition and make the symbol for wrapping addition long and unattractive. Make writing unsafe code harder. This is just basic psychology.

C has the same problem, they have functions checking for overflow, but they also have long and ugly names that discourage their use.

> modern hardware will just wrap if you don't check and that's cheaper

So you suggest that because x86 is a poorly designed architecture, we should adapt programing languages to its poor design? x86 will be gone sooner or later anyway.

Also, there are languages like JS, Python, Swift which chose the right path, it is only C and Rust developers who seem to be backwards.

show 1 reply
Asmod4ntoday at 3:45 PM

__builtin_add_overflow Exists and it’s basically free on most CPUs out there.

show 1 reply