
New things in clang land (5.0.0) - mrich
http://www.productive-cpp.com/new-things-in-clang-land-5-0-0/
======
ladberg
Hmm, the first example kind of bugs me. I get why they are doing it, but I
feel like there should be a better solution. Instead of cramming as much
optimization into undefined behavior as you can, maybe don't allow the
undefined behavior in the first place? I think if I had something like this
accidentally in my code then I would want it to tell me that something's wrong
instead of just giving bizarre results.

~~~
Athas
But it might not be undefined behaviour at compile-time. Consider if instead
of just 'f(nullptr)', the call in the main() function had been 'f(getchar() ==
'x' ? nullptr : &x)' (where x is some variable in scope). It cannot be known
until run-time whether a NULL pointer is being dereferenced, but since the
pointer inside of 'f()' is being dereferenced, the compiler can assume that it
will not be NULL.

~~~
ladberg
Sorry, I was referring to the program as a whole. I get why it did the
optimization for that one function in particular, but in this case, it can be
proven that the function call will result in undefined behavior and (in my
opinion, not necessarily the way the C standard works) it should be flagged or
not compiled.

~~~
cesarb
Do not put your faith in whole program optimization. If it can be proven that
the function call will result in undefined behavior, the compiler will assume
that the function will never be called. If it can be proven that it will
always be called, the compiler is free to assume that the program will never
be run, and optimize the whole program down to nothing.

That is, undefined behavior propagates not only forwards (if you dereference a
pointer, from them on you can be sure that it's not null), but also backwards
(if you dereference a null pointer, that's a contradiction since null pointers
can't be dereferenced, and the contradiction can only be resolved if the
statement is unreachable).

~~~
oconnor663
> If it can be proven that it will always be called, the compiler is free to
> assume that the program will never be run, and optimize the whole program
> down to nothing.

Does that happen when the compiler assumes you'll never take branches that
lead to UB, and then finds a path through your branches that more or less does
nothing? Or can it happen even if you're not branching at all?

Also, say my program is

    
    
        int main() {
            printf("hello world\n");
            do_some_UB();
        }
    

Is the compiler really allowed to produce a program that doesn't print?

~~~
masklinn
> Does that happen when the compiler assumes you'll never take branches that
> lead to UB, and then finds a path through your branches that more or less
> does nothing? Or can it happen even if you're not branching at all?

Yes and yes. How far it will propagate these backwards depends on the
compiler.

> Is the compiler really allowed to produce a program that doesn't print?

Yes. A program which contains UB is illegal, there are no guarantees about any
of its behaviour, including behaviour which precedes any possible actual
invocation of UB, this is pointed rather clearly by the standard:

> However, if any such execution contains an undefined operation, this
> International Standard places no requirement on the implementation executing
> that program with that input (not even with regard to operations preceding
> the first undefined operation).

~~~
oconnor663
Good heavens! :)

------
MichaelMoser123
actually address sanitizer has been ported to gcc, so it is no longer a clang
only thing. last time i checkted it did not not support stack switching
(cooperative scheduling). Is there any change in this area?

