> Every access (read or write operation, member function call, etc.) made through a glvalue expression of volatile-qualified type is treated as a visible side-effect for the purposes of optimization (that is, within a single thread of execution, volatile accesses cannot be optimized out or reordered with another visible side effect that is sequenced-before or sequenced-after the volatile access. This makes volatile objects suitable for communication with a signal handler, but not with another thread of execution, see std::memory_order). Any attempt to refer to a volatile object through a non-volatile glvalue (e.g. through a reference or pointer to non-volatile type) results in undefined behavior.
Which bit of "This makes volatile objects suitable for communication with a signal handler, but not with another thread of execution" is unclear?
In fact, Standards notwithstanding, real compilers routinely optimize away volatile operations if they deduce nothing can see the object -- e.g., it is on the stack, and its address has not been taken. And they will happily re-order reads from and stores to other objects around a volatile operation. Furthermore, caches don't know squat about volatile, so they will eagerly re-order the volatile ops, besides.
So, no, he did not have a point. He was just wrong, wrong, wrong. But it never caused him any personal distress.
You can use volatile as part of a suite of compiler specific tricks to implement higher level load acquire/store release operations on x86 (and load consume everywere else), but portably you can't do much.
Yes, he is wrong.