6 ms·
Ostensibly as a programmer you know the semantics of your programming language, so the compiler isn't doing anything unexpected here ;) So from its perspective
by Thiez 5y ago
Ostensibly as a programmer you know the semantics of your programming language, so the compiler isn't doing anything unexpected here ;) So from its perspective it is not doing anything unexpected to your code.
I think the real problem here is that people underestimate the complexity of C and C++. It often feels like it would be easy to guess what the assembly would look like for some snippet of C/C++ code (especially when it's not using any C++ features, such as the loop in the article) when we really should be thinking in terms of the abstract machine that the standard defines.
- AnIdiotOnTheNet 5y ago> Ostensibly as a programmer you know the semantics of your programming language, so the compiler isn't doing anything unexpected here ;) So from its perspective it is not doing anything unexpected to your code. I just don't think having 'gotcha' rules the compiler exploits to do whatever it wants regardless of programmer intent is a good idea, and that's how C/C++ treats UB. UB should be a compiler error and force the programmer to specify what they want the result to actually be so there are no assumptions on the programmer end and no surprises from the compiler.
- Denvercoder9 5y agoThis happens because (paraphrased) the standard dictates that loops without side-effects eventually terminate, and all other programs have undefined behaviour. You can't turn hitting that undefined behaviour into a compiler error, as distinguishing between the two requires solving the halting problem. You can remove the whole assumption, but that limits the optimization capabilities of the compiler. That gives a trade-off: do we want actual infinite loops, or do we want better optimizations? The second seems more useful to me, even though it might sometimes give surprising behaviour for the programmer.
- AnIdiotOnTheNet 5y ago> You can't turn hitting that undefined behaviour into a compiler error, as distinguishing between the two requires solving the halting problem. That's a fair point, but it still feels wrong to me that the compiler can throw away large chunks of code and change the outcome of the function silently.
- Blaisorblade0 5y agoThrowing away large chunks of code is what optimizers exist for! Sadly, most discussions of UB only show when it "goes wrong" (has surprising results), not when it goes right!
- Thiez 5y agoNote that the optimization discussed in the article does not actually involve UB. > UB should be a compiler error and force the programmer to specify what they want the result to actually be so there are no assumptions on the programmer end and no surprises from the compiler. Many types of UB are not easily detected at compile time, or cannot be detected in advance at all. For instance, prompting the user for an integer and incrementing it by 1 is UB when the user enters the maximum value of an integer. So should the compiler forbid adding two numbers unless you explicitly guard against overflow? Perhaps it should, but the resulting language definitely wouldn't look anything like C. Besides, it's not that the compiler is going out of its way to screw you over with a 'gotcha' rule, it's just optimizing using the assumption that your program is free of UB. As a programmer it is your responsibility that there is no UB. If you feel there are too many pitfalls you could use a different programming language, lobby the standards organization for a standard that has less UB, or use compiler options to detect it (e.g. ubsan for clang).