Hacker News new | ask | show | jobs
by mehrdadn 2230 days ago
Okay, you're very confused. You're getting it almost backwards.

Undefined behavior is behavior that the language does not define, not behavior that the implementation is prohibited from defining. That's why you can't treat it like (for example) a random-number generator. Implementations are well within their rights (i.e. 100% consistent with the language) to define previously-undefined behavior to be anything. They're also just as welcome to leave them undefined. Both are 100% consistent with the language and neither is "changing" the language semantics. No program that exhibited UB is going to misbehave somehow just because someone decided to define the behavior under UB. The semantics already allowed anything to happen. Whatever they define falls under "anything could happen".

Implementation-behavior is behavior that the the implementation is guaranteed to define. Like with UB, the implementation has freedom to choose a behavior. Unlike with UB, it is not allowed to leave that behavior undefined. So the program can be sure to have a well-defined output.

It is completely wrong to simultaneously say changing "wrap" to "crash" is "not changing semantics" and somehow "consistent" with the language rules, but that changing "undefined" to "wrap" is "changing semantics" and "not consistent" with the language rules. If the language wraps on overflow, then changing that to a panic is actively shrinking the set of valid programs; valid programs that used to behave one way now behave differently. (They crash!) The latter is merely expanding the set of valid programs; programs that had no rights to claim any behavior under UB now actually have a right to claim something under the implementation, but that doesn't change the behavior of previously-valid programs. They're still provided exactly the same guarantees they already were.

(P.S., UB isn't even a property of a program, but of an execution. But I'll leave that out since the simplified version is clearly confusing enough as-is.)

1 comments

I do absolutely understand that UB does not prohibit implementations from defining something. That’s part of the core of what we’re taking about! I’m saying rustc chooses to never do so. C and C++ compilers do choose to do so. That distinction is what we’re talking about.

(As well as that overflow is UB in one language and not another, of course.)

No comment on everything else I wrote beyond that 1 sentence? Your positions are quite contradictory, which is what I've been trying to explain in the entire comment.
I just don't think we're going to get anywhere, but wanted to correct the assertion that I do not understand this aspect of UB.
I mean, your positions are contradictory, but sure.