9 ms·
Undefined behaviour has meant undefined behaviour. That doesn't mean nasal demons. That means this: Possible undefined behavior ranges from ignoring the si
by to3m 11y ago
Undefined behaviour has meant undefined behaviour. That doesn't mean nasal demons. That means this:
Possible undefined behavior ranges from ignoring the situation
completely with unpredictable results, to behaving during translation
or program execution in a documented manner characteristic of the
environment (with or without the issuance of a diagnostic message),
to terminating a translation or execution (with the issuance of
a diagnostic message).
Permit me to suggest that when there is a choice between making things behave in a documented manner characteristic of the environment, or something else - don't go for the something else.
- cygx 11y agothe Standard imposes no requirements on undefined behaviour. The list you quoted is informative, to give us a basic idea what to possibly expect, not a list of things we may rely upon. Rejecting translation outright aside, undefined behaviour is the strongest language the standard uses for illegal constructs. I do not see it as undefined in the sense of lacking a common definition (eg is 0 a natural number, or not) but something that is undefined the way 0/0 is undefined in maths. In a way, the criticized behaviour of aggressively opimizing compilers is a consequence of ignoring the situation completely with unpredictable results. It's the same line of reasoning that makes restrict useful, just on steroids.
- to3m 11y agoWell I submit that as a simple question of quality of implementation, implementers should try their hardest to go for the something that behaves "in a documented manner characteristic of the platform"! But instead, they seem to pick something else. And I claim that this is not helpful to their users, who would be far better served by the characteristic-of-the-platform option.
- cygx 11y agoIt's really friction between incompatible visions of C: Some want it to be a portable wrapper over assembler with predictable semantics, others want it to run as fast as possible. Like it or not, the standard leaves the doorway open for the latter group to come up with increasingly aggressive optimization, only limited by their ingenuity.
- derefr 11y agoYou'd think that'd make things clear, then: if you want a compiler to error out on trying to compile a literal 0/0, then you'd probably also want the same behavior of trying to compile a literal dereference of 0, or a literal (INT_MAX * 2), or whatever else.
- cygx 11y agoYou missed the point of the analogy: It's not about how compilers treat the expression 0/0, but how mathematicians do. If that expression turns up in your calculation, you did something you were not supposed to do and have no one else to blame.
- derefr 11y agoNo, rebutting that was exactly my point: programming is, in some ways, a friendlier version of working on mathematical proofs, in that the compiler will tell you when you "did something you were not supposed to do." Programmers expect to be able to hack away like monkeys on typewriters, and just run into a virtual wall whenever they misstep. Compilers will error out when a programmer explicitly types "0/0", and that's a good thing. It'd be a good thing in the other cases, too.
- zAy0LfpBZLC8mAC 11y agoYou are still missing the point. Yes, compilers obviously should not intentionally produce unnecessarily destructive behaviour. But that is not what is happening. What if the code contains "x/y"? Now, the compiler can try to prove that x and y can never be 0 at the same time. But what if that proof doesn't succeed? Maybe x is user input, so who knows what the user will enter at runtime? Now, the language spec could specify that the computation of 0/0 always results in a runtime error. But if it did that, there might be target architectures where the code that would need to be generated to check for that case would have a 300% performance overhead versus code that does unpredictable stuff when it gets fed 0 for both x and y, but in every other case performs a perfectly predictable division. That slowdown would be inacceptable for computation-intensive code where a 0/0 could never happen by construction, even though the compiler can't prove it. And that is why the standard simply says "it's undefined behaviour".