One example of this article from a msdn blog made me ticker:
It says that this function:
void unwitting(bool door_is_open)
{
if (door_is_open) {
walk_on_in();
} else {
ring_bell();
// wait for the door to open using the fallback value
fallback = value_or_fallback(nullptr);
wait_for_door_to_open(fallback);
}
}
Can be optimized into this one:
void unwitting(bool door_is_open)
{
walk_on_in();
}
Because calling value_or_fallback(nullptr)
is undefined behavior (this is proven earlier in the article).
Now what I don’t understand is this: the run time enters undefined behavior only when it reaches that line. Shouldn’t the happen-before / happen-after concept applies here, in the sense that all observable effects of the first paragraph have be resolved before the run time enters UB?
There is a flow in the reasoning.
When a compiler writer says: we use Undefined Behavior to optimize a program, there are two different interpretations:
Thus, in your case:
nullptr
is Undefined Behaviorvalue_or_fallback(nullptr)
is Undefined Behaviorelse
branch is Undefined Behaviordoor_is_open
being false
is Undefined BehaviorAnd since Undefined Behavior does not occur (the programmer swears she will follow the terms of use), door_is_open
is necessarily true
and the compiler can elide the else
branch.
(*) I am slightly annoyed that Raymond Chen actually formulated it this way...