On 11/06/2021 11:37, Jonny Grant wrote: > Hello > This isn't real code, it's just an example to ask this question: > > Would GCC optimizer ever re-order these statements and cause a NULL ptr de-reference SIGSEGV? I recall reading a Chris Lattner paper indicating it could happen. > > void f(int * p) > { > if(!p) > { > return; > } > > printf("%d\n", *p); > } > > I which case, a lot of production code faces issues, must be changed to: > > void f(int * p) > { > if(p) > { > printf("%d\n", *p); > } > } These two functions have identical semantics. > > Jonny > The optimiser never (baring bugs in the compiler, but those are rare!) rearranges code in a way that changes side-effects in well-defined code. If code hits undefined behaviour, the compiler can do anything. Thus if you write: void f2(int *p) { int x = *p; if (p) printf("%d\n", x); } the compiler can reason that either p is null, or it is not null. If it is not null, the "if (p)" conditional is always true and can be skipped. If it /is/ null, then dereferencing it to read *p is undefined behaviour - and the compiler can assume the programmer doesn't care what happens. So the code can be optimised to: void f2(int *p) { printf("%d\n", *p); } If the compiler knows that on the target in question, it is perfectly safe (i.e., no signals or anything else) to dereference a null pointer, then in your original "f" the compiler could read *p before it tests p for null, but it could not do the printf before the test. (Sometimes for embedded systems the compiler knows that reading via a null pointer is safe.)