On an STM32 I set a flag in a timer interrupt with flag = 1; and the main loop waits with while (!flag) { }. Built with -O0 it works. With -O2 the loop never exits, although the debugger shows the interrupt running and writing the flag. Declaring the flag volatile fixes it.
Why does the optimiser break the original code? I also have a 32-bit tick counter written only by the ISR, and an event counter that the ISR increments and the main loop decrements. Is volatile enough to make those two safe?




