[1] I'm also ignoring the fact that volatile really doesn't have the right semantics in C++11/C11.
[1] I'm also ignoring the fact that volatile really doesn't have the right semantics in C++11/C11.
So let's not fix that, but invent new cruft.
C defines volatile for several purposes of its own, and that's it.
- In a function that uses setjmp, volatile must be used to mark variables that are modified after the context is saved with setjmp but before control returns with longjmp. Otherwise there is a problem, like the longjmp spuriously restoring the original values of those variables (due to those variables having been pulled into the machine state being saved and restored, like registers).
- When an asynchronous signal handler (e.g. for SIGINT) sets a global variable which is checked by the interrupted code, that variable has to be "volatile sig_atomic_t".
Any usefulness of volatile for actual concurrency is courtesy of the compiler, whether empirical or documented.
As an extension, MSVC did for a time add atomic and acquire/release semantics to volatile. This was deprecated because it broke too much stuff.
edit: after your edit, I'm not sure if you arguing for volatile-for-atomic or not.
Indeed I've worked with hardware where it was more obvious how to lower an atomic load or store than it was to lower a volatile load or store, because the technical definition of volatile really doesn't comport with the practical meaning of "don't optimize this" (crazy hardware does things like that).