Why can an optimizing compiler legally delete the null check in the second snippet, turning a crash-free program into one that dereferences null?
int* p = get();
int x = *p; // (1) unconditional deref
if (p) { // (2) check AFTER deref
use(x);
}