3 ms·
> 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 r
by 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.
- bluGill 7y agoThat happens once in a while when you try to exploit undefined behavior. I don't do that in my code. I use undefined behavior sanitizer to prove that statement (without that tool I make mistakes)
- mark-r 7y agoBut it's not the programmer trying to exploit undefined behavior, it's the compiler. That's just wrong. How would you check for a null pointer in a way that the compiler can't optimize away?
- eru 7y agoLike this: if (ptr) *ptr = 2; I sort-of agree with you that 'exploiting' undefined behaviour is a bad thing. But that's what C (and C++) are all about: the undefined behaviour everywhere allows the compiler to make lots of optimizations without having laboriously to prove that they are safe. And those languages are all about speed at the expense of safety. If you want (more) safety, there are languages for that. Including C dialects you get via various compiler flags. Eg the Linux kernel uses a special gcc compiler flag to keep all null checks. For this very reason. See https://people.csail.mit.edu/nickolai/papers/wang-undef-2012-08-21.pdf https://people.csail.mit.edu/nickolai/papers/wang-undef-2012... for an overview with examples from the kernel, and lots of cases where the kernel authors opted for a compiler flag to effectively use a more defined dialect of C.