So there is a path, but it has to take an upgrade-path into account for big legacy projects.
In practice, moving to a new compiler can be a big project for companies with larger code bases. Sensible deprecation of features could (and in practice) is part of that.
Even though the standard is quite careful, in practice big C++ projects sometimes rely on non-conforming behavior of the specific compiler version they use. An example is the MSVC template support which allowed constructs that the standard didn't.
The committee does a lot of work to keep the standard compatible with c++ as it is used and this proposal seems to be a good example of them trimming out dead and bloated parts, without negatively impacting existing code.
The original proposal for that deprecation points out a lot of issues. Basically it boils down to the fact that many operations were badly specified, outright misleading, predate the c++ memory model or were artifacts of maintaining the parallel to const that volatile had in C at a large cost and without people actually using it, one example they could track down even noted how it did not behave the same way as primitives would.
Your example is a really poor one. The volatile keyword was only used to provide hints to the compiler on whether or not it could apply some optimizations. Omiting a volatile keyword is perfectly backward compatible, as is compiling code without support for volstile. Thus the only practical consequence of adding/removing random volatile keywords from your source code was how your build could (and not should) be optimized.
I'm of the general opinion that what people think volatile does vs. what the compiler really does is quite different. Perhaps the situation has improved since this paper appeared.
Formally ignoring or forbidding volatile where it presently doesn't mean anything (despite fervent wishing) wouldn't break anything. Compilers would of course continue supporting whatever they do, but would be allowed to warn about dodgy uses.
On MSVC, volatile has traditionally meant something akin to atomic. It still will, regardless of what the Standard says and other compilers do.
You can't call non-volatile methods of volatile objects (just as you can't call non-const methods of const objects), and you can overload methods on volatility like constness. It may not have the "don't cache this in a register" semantics it did in the single-core C era, but it can't just be discarded.
Code that compiles today would still compile if restrictions were lifted, modulo overload resolution changes that might introduce new ambiguities or name collisions.
"Can't" is a big word when applied to the ISO committee. They would want to consider the magnitude of consequences. Since all implementations would provide a "make like before" switch, consequences would be limited.
They can choose to make breaking changes, but they can't eliminate "volatile" without breaking anything. I've definitely seen code that relies on it, albeit for strange reasons.
No, at best you saw code that expects the compiler to not apply specific optimizations that C++ doesn't suggest or enforce. It's a compiler issue, thus if anything that code needs to be compiled accordingly.
No, there are other reasons to use volatile declarations that have nothing to do with the original purpose, and that are completely unaffected by any potential effect on optimization. At the level I have seen, it is used as a simple tag to generate a type related to T that is neither T nor const T.
I use volatile on memory mapped input ports. It tells the compiler that if I am reading twice from this address without writing to it in between, don't optimize out the subsequent reads because this is not a memory location whose contents are under the control of the program. If the compiler ignores this, the software most certainly will break and break hard. For some applications the results will be crashed vehicles, runaway industrial processes, and dead people. Compilers are not free to ignore volatile and it is not a suggestion to the compiler, it is a directive which must be obeyed. Compilers that don't do this are broken compilers.
Thanks, not the first two. I'm not sure what volatile pass by value means and did not know that that was ever a thing. The third one, yeah, I use that, and you have it marked as non deprecated, so that's good.
So there is a path, but it has to take an upgrade-path into account for big legacy projects. In practice, moving to a new compiler can be a big project for companies with larger code bases. Sensible deprecation of features could (and in practice) is part of that.
Even though the standard is quite careful, in practice big C++ projects sometimes rely on non-conforming behavior of the specific compiler version they use. An example is the MSVC template support which allowed constructs that the standard didn't.