5 ms·
> It therefore has no valid executions. The compiler is legally allowed to generate whatever code it wants If the compiler concludes that the program has no va
by antientropic 9y ago
> It therefore has no valid executions. The compiler is legally allowed to generate whatever code it wants
If the compiler concludes that the program has no valid executions, then why not just generate an error message at compile time?
I wonder in what other engineering disciplines this kind of attitude (i.e. silently punishing users for mistakes by generating arbitrarily misbehaving code) is considered acceptable. It seems unethical to me. Perhaps compiler writers should think more about what constitutes sound engineering, rather than what happens to be permitted by The Standard.
- to3m 9y ago"These people simply don't understand what C programmers want": https://groups.google.com/forum/#!msg/boring-crypto/48qa1kWignU/o8GGp2K1DAAJ https://groups.google.com/forum/#!msg/boring-crypto/48qa1kWi... "please don't do this, you're not producing value": http://blog.metaobject.com/2014/04/cc-osmartass.html http://blog.metaobject.com/2014/04/cc-osmartass.html "No sane compiler writer would ever assume it allowed the compiler to 'do anything' with your code": http://article.gmane.org/gmane.os.plan9.general/76989 http://article.gmane.org/gmane.os.plan9.general/76989 "Everyone is fired": http://web.archive.org/web/20160309163927/http://robertoconcerto.blogspot.com/2010/10/strict-aliasing.html http://web.archive.org/web/20160309163927/http://robertoconc... The really strange this is: there's probably tons of places that the compiler takes advantage of undefined behaviour, and nobody notices, and in fact is grateful of the magic speed improvement that comes for free simply from adding -O3 or whatever. And these are then used to justify the undefined behaviour that people find slightly mystifying, or that cause actual problems in practice (interestingly these always seem to be related, as in this case, to things that can be statically proven to have NULL-related undefined behaviour). But why not treat these two cases differently? The customer is always right!
- umanwizard 9y agoWhy do you assume it's so easy for the compiler to tell the difference between the two cases? From this optimization pass's perspective, it has proved that in a legal program `Do` can only have one possible value, and simplified the code appropriately. Most of the time this sort of optimization is correct and the programmer wants it; how is it supposed to figure out that this time the programmer had some different semantics in mind?
- to3m 9y agoI'm sorry, "legal" is not a term defined by the standard.
- titzer 9y agoOh, I totally agree. The history of C++ is basically a long argument between compiler writers and language designers, with the compiler writers inventing new optimizations which violate language semantics, a fight ensuing, undefined behavior somehow entering the equation, and then the language designers lose the argument, and the spec is changed. E.g. one justification given for signed integer overflow being undefined behavior is so that compilers are legally permitted to optimize "(a + k) < (b + k)" to "a < b", which is not correct in the case of overflow.
- tom_mellior 9y ago> If the compiler concludes that the program has no valid executions, then why not just generate an error message at compile time? I agree that that would be nice to see in this case, and it seems like this particular case would be low-hanging fruit, but it's not that simple. In particular, the compiler in this example most likely does not reason globally; it never actually decides that "the program has no valid executions". It does a series of local transformations, presumably based on facts of the form "if we can reach this point, then certain values are invalid". Another thing about such error messages would be that they would push compilers more in the direction of verification tools, which they aren't, and cannot be. Consider: int f() { return 1 / 0; } int g() { int a = 0; return 1 / a; } Clang warns about the first function, but not about the second one. If it warned about the second one, I could write a third function that always divided by zero, but that it could not warn about. If it learned to do that, I would find a fourth one, etc. This is an arms race that compilers cannot win, and they shouldn't try. You should use separate verification tools for that, which do the opposite of compiler warnings: They don't reject the program if it's trivially buggy, they reject it unless you prove that it is not buggy. If compilers had more such warnings, programmers would be tempted to say "look, there is no warning, the code must be fine". That's the whole "if it compiles, it's correct" approach that gives some gullible people a false sense of security in other languages.
- mannykannot 9y agoI certainly hope that there are not many programmers thinking "if it compiles, it's correct" after having made their first logic error, though I realize some Haskell programmers make statements that are close to that. Clang and gcc will warn you about some of these issues if you give them the right flags (so much so that -Wall no longer means literally all warnings, IIRC), but then you run into static analysis' problem of burying you in false positives for conditional / data-dependent undefined behavior. I have found it instructive to play with Dafny, one of the languages where the compiler does require you to prove that a variety of bugs will not occur, but 'play' is the operative word here. It is not a feasible option for C. C has always been a language for (among other things) creating optimized code, but the implication of that has changed. Originally, it meant / required being 'close to the metal', but since then, effective automated optimization has come along, and the metal itself has become considerably more complicated (partly as a consequence of more capable optimization). As C programmers, we should understand that these changes have occurred, and what they mean for programming in C - or not use the optimizer.