Hacker News new | ask | show | jobs
by steveklabnik 2230 days ago
The practical benefit is not in the wrapping specifically. The difference is in it being UB vs not UB; that is, overflow is a "program error" not UB, and so the language defines how implementations must handle this error.

You aren't supposed to rely on this semantic, as it's an error. If the checks get cheap enough, rustc will also check in release.

1 comments

I mean, the post seemed to be arguing that the wrap-around is somehow beneficial, so I'm not sure you're saying the same thing. But if all you want is check + crash when that happens then can't you just use a compiler flag or a different data type or something else for that in C++?
It is beneficial that the behavior is defined, and therefore consistent. So you don't run into cases where it works on your laptop, but not on your server. Also, in this particular case, overflowing is probably not terrible, since you are computing a hash code. The worst case is that the distribution may not be as even as you hoped.
> It is beneficial that the behavior is defined, and therefore consistent. So you don't run into cases where it works on your laptop, but not on your server.

I already don't run into such cases though? Do you run into cases where changing an overflow to wrap-around (e.g. maybe via unsigned?) makes it suddenly your code work on 2 machines, whereas leaving it as overflow makes it work on 1 machine but not the other?

That was the example given in the original article
Yes, but I was asking about your experience.
I’m not saying that the wrapping behavior is beneficial. I’m saying that having it be not UB is beneficial.
But if all you want is check + crash when that happens then can't you just use a compiler flag or a different data type or something else for that in C++?
Different type? Sure. Disadvantage is that it’s not pervasive. Compiler flag? Probably, I am not an expert on compiler flags that change language semantics; we don’t do that in Rust, but I know C and C++ compilers do.
> Compiler flag? Probably, I am not an expert on compiler flags that change language semantics; we don’t do that in Rust, but I know C and C++ compilers do.

What do you mean? Is Rust's -C overflow-checks just a joke then? https://doc.rust-lang.org/reference/expressions/operator-exp...

Okay, so let's review the language's rules here:

* There are two modes for overflow checking: enabled, and default.

* If overflow checking is in "enabled" mode, overflow results in a panic.

* If overflow checking is in "default" mode, the results are two's compliment wrapping.

* Debug builds are "enabled" mode.

(There's a few other details, but this is good enough for our discussion. See https://github.com/rust-lang/rfcs/blob/master/text/0560-inte... )

Rustc implements this as follows:

* When debug_assertions is on, it's in "enabled" mode.

* Otherwise, it’s in “default” mode.

* -C overflow-checks turns on "enabled" mode, regardless of other settings.

This is completely consistent with the rules of the language. If these checks ever get cheap enough, rustc may even start to turn them on by default, which is also acceptable under these rules. We'll see if that ever happens, though.

Compiler flags are not part of the language, so not portable.

Using a different data type? You'd have to use arbitrary precision numeric data types to avoid this. After all, you can still overflow 64-bit ints.