To improve performance, compilers, optimizers, and hardware fix instructions. Consider:
// thread 1: int x; bool x_init; void init() { x = initialize(); // no use of x_init in initialize() x_init = true; // ... }
For this piece of code, there is no given reason to assign x before assigning x_init. The optimizer (or the hardware scheduler instruction) may decide to speed up the program by doing x_init = first. We probably wanted x_init to indicate whether x was initialized with an initializer () or not. However, we did not say that, therefore, the hardware, the compiler and the optimizer do not know what.
Add another thread to the program:
// thread 2: extern int x; extern bool x_init; void f2() { int y; while (!x_init) // if necessary, wait for initialization to complete this_thread::sleep_for(milliseconds{10}); y = x; // ... }
Now we have a problem: thread 2 can never wait and thus assign uninitialized x to y. Even if thread 1 does not set x_init and x to "Wrong order, we can still have a problem. There are no x_init assigned to thread 2, so the optimizer may decide to un-evaluate! X_init from the loop, so thread 2 never sleeps or sleeps forever and ever.