I've been longing for a C compiler with a "sane optimizations only"-switch like forever. I'd gladly give up on the additional couple of per cent speed improvement obsessive compulsive compiler writers managed to eke out by ignoring the source codes' obvious intentions and defending it with "but technically it's undefined behaviour"!
Everyone posts a comment like this every time undefined behavior surprises someone. But the reality is that the reason why C remains alive is that compiler writers have managed to make it fast. It is not "a couple of percent": these kinds of optimizations can make an enormous difference when, for example, they're the difference between vectorizing a loop and not doing that.
Compiler writers are not "obsessive compulsive". They respond to the demands of their customers. Frequently, the reason why these optimizations exist is that someone filed a bug asking "why doesn't the compiler do this seemingly-obvious optimization?" Often, the only reason these seemingly-obvious optimizations work at all is by exploiting undefined behavior.
The craziness for C optmizer tricks is in many cases plain phsycologic.
As an example, it doesn't matter that it does in 5ms what it takes to do in 15ms without the optimization, if in the end anything less than 20ms doesn't have visibile outcome.
Actually there is a remark from a famous compiler write (female), which I don't recal the name now, that C brough back into the stone age what the optimizers were already able to do for Algol family of languages.
This is visible in PL/8 research paper, a compiler that already used compiler optimization passes in the 70's, nowadays mostly common on LLVM.
> As an example, it doesn't matter that it does in 5ms what it takes to do in 15ms without the optimization, if in the end anything less than 20ms doesn't have visibile outcome.
That hasn't been true ever since power consumption started mattering.
If it really mattered at that level, people would have already stopped trying to do Web based OS or applications for mobile phones.
Also Apple, Google and Microsoft would expose the complete set of mobile and watch OS APIs to C and C++ developers, which they don't. They are kept down to the bare minimum for the upper OS layers.
If you mean takes 15ms vs 5ms to compile yes. However if you're talking executions speed those low hanging fruit optimizations were picked in the 1980's. What we're talking about here are optimizations that speed up some obscure benchmark on a disused architecture by 5%. Bonus no telling if performance is worse on next years silicon.
The statement is actually part of the "Coders at Work" interview, where she explains why "how C has grievously wounded the study of computer science." from her point of view.
How do you know it would only be a few percent? What if such a switch made your code ten times slower? Without actually reading the clang code and seeing what all the optimization passes do, I don't see any a priori reason for assuming it would be a few percent rather than 10x.
What would that look like? How would this prevent me from returning a pointer to a stack frame that no longer exists, just for example? Clearly undefined behavior, but C doesn't seem capable of expressing this safely, with or without the compiler's help?
It wouldn't make it safe; it would make it so that the consequences of returning that pointer are just the same as if you had written an assembler routine returning that pointer. On all common hardware, that would be none if the pointer is never used; on most common hardware, it would be none if the pointer is never used in a call at least equally deep — but anyway, you'd get whatever the machine does, and if you don't like it, that's your problem. In pre-UB C, the ‘spirit of C’ that C89 was intended to maintain was that you get what you wrote.
By contrast, modern ‘undefined behaviour’ means that if you return that pointer — even if it is never actually used — the compiler can throw away all the code leading up to that point (including external side effects) on the grounds that it “can't happen”. You get much less than what you wrote.
How would this prevent me from returning a pointer to a stack frame that no longer exists, just for example?
It doesn't, but the outcome would be predictable: the pointer will always be pointing there.
I assume you mean by "stack frame that no longer exists" something like returning a pointer to a local variable; what that would do is return the address where the variable was --- the memory address still exists, so "no longer exists" is somewhat of a misconception here.
What "sane optimisations" mean is that the compiler won't e.g. decide to remove all the code following any call to that function, just because you "invoked UB".
Maybe you won't quickly find a practical and non-contrived application for this specific case, but there are plenty of others. UB breaking buffer overflow checks springs to mind.
I've been longing for a C compiler with a "sane optimizations only"-switch like forever. I'd gladly give up on the additional couple of per cent speed improvement obsessive compulsive compiler writers managed to eke out by ignoring the source codes' obvious intentions and defending it with "but technically it's undefined behaviour"!