Hacker News new | ask | show | jobs
by dataflow 2230 days ago
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++?
2 comments

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.

So let's review where we are right now. C++ left the entire thing undefined, which gave compilers the complete freedom to add flags that define e.g. wrap-around or trapping or other behavior. I suggested you can use such flags if you want. You complained about that and said it's "changing" language semantics... despite the fact that it's 100% consistent with the "rules of the language". You even went on to claim "we don't do that in Rust". All right. So I pointed you to a Rust compiler flag that changes the default wrap-around to a panic. Now you're saying that's not changing Rust's language semantics... and your defense is "it's consistent with the rules of the language"...?!
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.