Template:cpp/atomic/atomic-vs-volatile

Within a thread of execution, accesses (reads and writes) through cannot be reordered past observable side-effects (including other volatile accesses) that are  within the same thread, but this order is not guaranteed to be observed by another thread, since volatile access does not establish inter-thread synchronization.

In addition, volatile accesses are not atomic (concurrent read and write is a ) and do not order memory (non-volatile memory accesses may be freely reordered around the volatile access).

One notable exception is Visual Studio, where, with default settings, every volatile write has release semantics and every volatile read has acquire semantics (Microsoft Docs), and thus volatiles may be used for inter-thread synchronization. Standard semantics are not applicable to multithreaded programming, although they are sufficient for e.g. communication with a  handler that runs in the same thread when applied to  variables.