Turning Text Into Instructions
The Compiler Deleted Your Safety Check Because You Had Already Broken the Rule
Last timeMaking It Faster Without Changing It
A language rule you did not know you made is a fact the optimiser is entitled to assume. Here is one real case followed from the source to the surprising output.
The promises you made
Every language definition has a list of things a program must not do. Reading
through a reference that points at nothing. Reading past the end of an array.
Letting a signed number exceed its range. Using a value that was never set.
The important part is what the definition says about a program that does one
of these anyway. It does not say the result is wrong, or that it varies by
machine, or that it is left to the implementation. It says nothing at all. The
behaviour is undefined, which means the language has made no promise about
what the program does from that point, or indeed before it.
Put that next to the rule from the previous lesson. An optimisation must
preserve the observable behaviour of the program. If the program has no defined
behaviour, there is nothing to preserve, and every transformation is correct.
That sounds like a lawyer trick and it is not. A compiler cannot generate code
for a program whose meaning the language declines to specify. It has exactly
two options: refuse to compile anything that might do such a thing, which is
impossible for the reasons in lesson three, or assume it does not happen. Every
compiler takes the second option, and so would you.
Assuming it cannot happen
The assumption is more powerful than it first appears, because it works
backwards as well as forwards.
| step | step | what the compiler knows | what it concludes | what happened |
|---|---|---|---|---|
| 1 | 1 | this line reads through the reference p | nothing yet | An ordinary operation. The compiler emits a load and moves on, or so you would expect. |
| 2 | 2 | reading through a reference is undefined | if this program is correct then p points | The language rule, turned around. The program is assumed correct, so the condition that would make it incorrect must be false. |
| 3 | 3 | a later line tests whether p points at n | the test is false, because that was esta | The crucial move. The fact flows forwards from the read to the test, even though a human reads the test as the thing that establishes the fact. |
| 4 | 4 | one arm of the test can never be taken | delete the test and the arm | Ordinary dead code removal, applied to a fact that came from the language definition rather than from anything the programmer wrote. |
what was written:
value = read the field of p
if p points at nothing then
report an error and return
use value
what the compiler derives:
the first line is undefined if p points
at nothing, so p points at something
therefore the test is always false
therefore the error path is unreachable
what is generated:
value = read the field of p
use valueOne case, all the way through
Notice the ordering mistake at the heart of it. The author used the reference
on the first line and checked it on the second. Written the other way round,
the check comes first, nothing undefined has happened by the time the compiler
reaches it, no assumption is available, and the check stays.
This is why the advice is always to check before you act. It is not a style
preference. In the first order, the check is dead code as a matter of language
definition, and no compiler is required to keep it.
The lesson stops here
1 more paragraph to go
You have read the opening. The rest of the argument, the problems that check whether it landed, and the lines worth keeping at the end all come with a plan.
The first lesson of every course in the library reads the whole way through, free, so you can see exactly what the rest of them are.
See the planThe contentsThis is the reading half
Starting the course gives you your own copy of it. Every idea on every page has problems standing under it, marked with a reason rather than a tick, and any sentence you do not believe can be opened and argued with. None of that can happen on a page nobody owns.
The contents