5 ms·
> Making assumptions about the value of a pointer based on UB is not ignoring the situation But it is? Out of all situations, you ignore those that invoke UB.
by aw1621107 7y ago
> Making assumptions about the value of a pointer based on UB is not ignoring the situation
But it is? Out of all situations, you ignore those that invoke UB. It's technically correct, but can produce bad results. What you want is to ignore the undefined behavior itself, and to treat the code as conforming. That's an equally valid interpretation, and the only way to definitively get one interpretation over the other is for the standard to change that wording to say so.
- acqq 7y ago> The only way to definitively get one interpretation over the other is for the standard to change that wording to say so. No. If the interpretation of the standard results in a behavior that makes the result obviously worse, nobody should favor such an interpretation. Even if the behavior is "undefined" as per standard, that doesn't mean that any compiler should "define" its own interpretation and implementation in a way to make every resulting program worse. They obviously "can" and obviously are already doing this, but even that doesn't make such an approach good or desired by any user of that compiler.
- aw1621107 7y ago> If the interpretation of the standard results in a behavior that makes the result obviously worse, nobody should favor such an interpretation. This would be true if everyone actually agreed that the more aggressive interpretation is obviously worse. Since said interpretation is claimed to result in better performance, though, it's not very clear-cut. That's the nature of ambiguity; either you rely on convention to establish a canonical behavior, which doesn't appear to be likely to happen any time soon and isn't guaranteed to remain the same over time, or you change the wording to no longer be ambiguous.
- DougBTX 7y ago> to make every resulting program worse. That's the crux of the issue though, isn't it. I'd like to think that the compiler developers are not programming at random, and that the optimisations do improve the compilation of code that only uses defined behaviour. If the only defined value for a condition is effectively: if (false) { ... } surely removing the branch is the best thing to do, regardless of what is inside the braces? If a language makes it easy to accidentally write if (false) when the programmer was trying to test some real condition, then surely that's a problem with the language, not the compiler.
- acqq 7y agoBut it's not "if (false)" that was originally written. It's the problem only when the language lawyers search for the "loopholes in the standard" to derive the meaning that is turning if (make sure something bad is not going on) { do_something } to the following: "I clever compiler author devised a way to analyze do_something and I see that you the writer of the code managed to write do_something in a way that can be considered "undefined behavior" according to this standard I'm using, therefore I am "allowed" to also remove the "if (make sure something bad is not going on)" to... nothing! See how fast the resulting code now is!" It's searching for the loopholes to do something directly against the intention of the writer of the code that people have problems with. In that light I fully agree with Linus: https://lkml.org/lkml/2018/6/5/769 https://lkml.org/lkml/2018/6/5/769 "I've said this before, and I'll say it again: a standards paper is just so much toilet paper when it conflicts with reality. It has absolutely _zero_ relevance." "There are competent people on standards bodies. But they aren't _always_ competent, and the translation of intent to English isn't always perfect either. So standards are not some kind of holy book that has to be revered. Standards too need to be questioned."
- bluGill 7y agoI'm glad my compiler searches for those situations and removes the unneeded if. I write a lot of generic code - often I need the if only in some situations and write it trusting the compiler will figure out the situations I don't need it and remove the if. Without this I'd have to spend a lot of effort maintaining hundreds of almost the same copies of my code different only where there is a might or might not be needed if. Not to mention all the likely bugs when someone doesn't select the right version of my code to use.
- mark-r 7y agoIn the given example, the if check for null was NOT unneeded at all, it was vital for proper program operation. Optimizing it away caused a bug that should not have occurred.
- 7y ago
- steerablesafe 7y ago> Even if the behavior is "undefined" as per standard, that doesn't mean that any compiler should "define" its own interpretation and implementation in a way to make every resulting program worse. The standard offers no interpretation of any undefined behavior, that's literally what meant by undefined. There is no execution of a program that contains UB that could be considered 'valid' by the standard. The compiler has no choice, it has to define its own interpretation.
- eru 7y agoTo make matters worse, undefined behaviour doesn't just exist at runtime. It can also happen at compile time etc. And it is allowed to time travel.
- acqq 7y ago> The standard offers no interpretation of any undefined behavior "The standard" is not compiling my program, the real compiler is doing that, and the authors of that specific implementation should do the right thing, in spite of the standard leaving something "undefined." > The compiler has no choice, it has to define its own interpretation. Correct. And it can define it as to not to be an adversary to the writer of the code.
- ryandrake 7y agoWhat is the “right” thing to do with UB, and who defines what is right, if not the standard? You?
- acqq 7y ago> What is the “right” thing to do with UB It is actually quite clear in most of specific cases, as Linus pointed even 18 years ago: https://gcc.gnu.org/legacy-ml/gcc/2002-01/msg00418.html https://gcc.gnu.org/legacy-ml/gcc/2002-01/msg00418.html "When it comes to optimization, there are things that are "obvious", and that will never generate any discussion at all, because they are faster ways of getting the exact same result, with no question about it. Nobody will ever fault a compiler for evaluating constant expressions at compile-time rather than doing the math at run-time and getting the same result. The two are indistinguishable from a result standpoint. But optimizations that can change the value of an expression are slightly different. They should make sense. You should be able to _explain_ them." "If you cannot explain the results, you end up having to argue about word-weaseling in the standard, and people _will_ disagree on what the damn thing means. Because standards aren't mathematically exact things."