I read it all. Here's something that might surprise you.wgarvin wrote:bob, I humbly suggest you take an hour and read each of these links with an open mind. I know it seems like a waste of time because you think you already know how it works. But just for an hour, forget what you know and read what these two experts have to say about the topic of undefined behavior:
(1) Chris Lattner, primary author of LLVM and the clang optimizing compiler. Chris is a bona-fide expert on compiler optimization and knows more about undefined behavior than any ten average programmers combined.
* LLVM Project BLog: What Every C Programmer Should Know About Undefined Behavior, Part 1 / 3
* LLVM Project BLog: What Every C Programmer Should Know About Undefined Behavior, Part 2 / 3
* LLVM Project BLog: What Every C Programmer Should Know About Undefined Behavior, Part 3 / 3
(2) John Regehr, associate professor of CS at University of Utah. He does research on software correctness, including things like compiler fuzzing, static analysis of source programs to find undefined behavior, etc. Using fuzzing and test-case-reducing tools he and his students wrote, Regehr has reported many hundreds of bugs in most of the widely-used optimizing compilers (GCC, clang, etc.) and helped popularize that style of compiler testing.
* A Guide to Undefined Behavior in C and C++, Part 1 of 3
* A Guide to Undefined Behavior in C and C++, Part 2 of 3
* A Guide to Undefined Behavior in C and C++, Part 3 of 3
* Integer Overflow Paper
* Winners of a contest to find the most surprising code snippet affected by undefined behavior
If you read these pages with an open mind, you may come away with a new respect for (and perhaps a healthy fear of) undefined behavior.
I think most programmers who use the C and C++ languages don't really understand what they are messing with when they stray into 'undefined' territory. They think the C language closely maps to what the underlying hardware does, so anything you write in C will somehow be mapped in a sensible way. This is only true for the parts of the language that are NOT declared as 'off limits' by labelling them as 'undefined behavior'. If you stray into UB territory, nine times out of ten you'll get away with it and the tenth time you'll get ripped apart by a rabid bear. Or something equally unpleasant.
Most programmers just don't know about this. If something happens to work on their compiler, they assume it is OK. They are blissfully unaware of how close they came to disaster (and how their code is a time-bomb that might someday fail in a surprising way). Chris even explains how LLVM takes pains to try and do the 'sensible' thing for some cases of undefined behavior, because in those cases if the compiler actually exploited it to the fullest, too many existing programs would not run correctly.
Not one new thing did I see. I lived thru the 70's and 80's when optimizers were just starting to get good. I attended ACM conferences where these topics were discussed. I listened to similar arguments for Fortran, C, you-name-it. I listened to the optimizer guys explain why they could optimize better if they could take advantage of certain assumptions such as no signed overflow. The general take on all of that, by those present, was a simple "bullshit." There are reasonable optimizations, from constant folding to common subexpression elimination, to moving loop invariant code out of the loop. the list goes on and on. And then there were those unsafe optimizations that could break a program.
The arguments raged just as much back then as they do now. I am not supposed to take advantage of undefined behavior, yet the compiler optimizer guys are allowed to do so. Even to the extend of breaking a working program. And the ultimate bad news is most of those unsafe optimizations are not very significant in most programs. Who REALLY does "if (a + 1 > a)"???
I didn't see anything there that sways my opinion of any of this, sorry. I STILL believe the compiler's job is to give me a higher-level way of expressing ideas so that I can write code quicker and debug it faster. Not to try to mangle code because the standard writers could not agree on a specific behavior, and therefore, they chose to leave it open. This is not a war of cleverness. It is a war of productivity. And this Apple change was anything but pro-productivity.