News for hackers. Stuff that matters.
Re:What every compiler writer should know about programmers ... by kazinator on Thursday March 03, 2016 @08:26PM (#11221404)
Optimizations based on undefined behavior are actually based on the belief that the code in question doesn't have undefined behavior (that the programmer is taking care of any possibility of undefined behavior, where that possibility exists).

This assumption should be made only if the programmer who wrote that code is a machine: a machine translating something which itself doesn't have undefined behavior, into C that doesn't have undefined behavior.

That assumption should not be made when the programmer is a person. Or, if the assumption is used, it should be accompanied by a diagnostic. "I'm expressing what appears to be your intent using a more efficient approach, which breaks in a surprising way if you made a mistake."

For instance, consider

   int compare(int x, unsigned char y)
   {
     return x + y > x;
   }
This is always true, or else the behavior is undefined. So it can be replaced with:

   int compare(int x, unsigned char y)
   {
     (void) x; /* somewhat accepted de facto idiom for ignoring arguments */
     (void) y;

     return 1;
   }
And GCC does turn it into "return 1". But why the hell would a human write a complicated function in place of just constant 1?

If a machine generated this due to following a template of code, that is understandable, and making it return 1 is helpful --- assuming that the generator is carefully written to avoid relying on undefined behavior.

Even if the generator actually relies on undefined behavior, the issue can be fixed in the generator, which can be run to regenerate all the code; but there is no such easy band-aid for human-written code. (A code generator can even have a catalog of what version of what compiler brand supports what undefined behavior in what way, and tune its output accordingly to what compiler is used in the subsequent pass.)

What is unhelpful on the part of compiler writers is supporting some undefined behavior as a de facto extension for many years, and then backpedaling on it.

One day your code that depends on signed integers having two's complement "odometer wraparound semantics" stops working after years or decades because of some compiler cowboy who was in millennial kindergarten when that code was written.

Re:What every compiler writer should know about programmers ... by nikic on Friday March 04, 2016 @06:41AM (#11223142)
What I think many people fail to realize is that a large part of the code as a C compiler sees it is machine-generated. While I certainly do not tend to literally write out `if (1 != 0)` conditionals in my code, these and other similarly trivial expressions, will be introduced en-masse after macro expansion and aggressive inlining.

And in this context, macro-expanded, inlined code, exploiting the assumption of no undefined behavior occurring starts making a lot more sense. Sure, if you consider something like

    int x = *ptr;
    if (ptr != NULL) {
        *ptr = 1;
    }
you may not unreasonably say that, as there is an explicit ptr != NULL check in there, probably that's what the programmer intended -- so we should not replace ptr != NULL with a constant 0 because that pointer was already dereferenced.

However if the real code is

    int x = *ptr;
    do_something_with_ptr(ptr)
and the do_something_with_ptr() function just happens to contain a NULL-check at some point (because it is written for a more generic purpose and not use in just this place), then not dropping that NULL-check becomes a very significant missed optimization opportunity.

If the compiler wouldn't optimize that out of consideration for the possibility of the former hand-written code, that would incur costs on the programmer. He might have to split do_something_with_ptr() into two functions, one doing NULL checks and one not doing it. He may have to add explicit compiler assumption / unreachability annotations.

The whole argument goes both ways, performing optimizations that break broken code has a cost (people have to fix it) and not performing those optimizations for working code (people have to manually optimize it).

Re:What every compiler writer should know about programmers ... by rcfox on Thursday March 03, 2016 @08:39PM (#11221461)
(x + 0 is not greater than x.)
Re:What every compiler writer should know about programmers ... by kazinator on Thursday March 03, 2016 @08:50PM (#11221510)
Thanks for that observation; it should be >=.

I will leave that as it is so that your comment makes sense; let this be the erratum.