There are a couple of questions on this site asking whether using a volatile
variable for atomic / multithreaded access is possible: See here, here, or here for example.
Now, the C(++) standard conformant answer is obviously no.
However, on Windows & Visual C++ compiler, the situation seems not so clear.
I have recently answered and cited the official MSDN docs on volatile
Microsoft Specific
Objects declared as volatile are (...)
- A write to a volatile object (volatile write) has Release semantics; a reference to a global or static object? that occurs before a write to a volatile object in the instruction sequence will occur before that volatile write in the compiled binary.
- A read of a volatile object (volatile read) has Acquire semantics; a reference to a global or static object? that occurs after a read of volatile memory in the instruction sequence will occur after that volatile read in the compiled binary.
This allows volatile objects to be used for memory locks and releases in multithreaded applications.
[emphasis mine]
Now, reading this, it would appear to me that a volatile variable will be treated by the MS compiler as std::atomic
would be in the upcoming C++11 standard.
However, in a comment to my answer, user Hans Passant wrote "That MSDN article is very unfortunate, it is dead wrong. You can't implement a lock with volatile, not even with Microsoft's version. (...)"
Please note: The example given in the MSDN seems pretty fishy, as you cannot generally implement a lock without atomic exchange. (As also pointed out by Alex.) This still leaves the question wrt. to the validity of the other infos given in this MSDN article, especially for use cases like here and here.)
Additionally, there are the docs for The Interlocked* functions, especially InterlockedExchange
with takes a volatile(!?) variable and does an atomic read+write. (Note that one question we have on SO -- When should InterlockedExchange be used? -- does not authoritatively answer whether this function is needed for a read-only or write-only atomic access.)
What's more, the volatile
docs quoted above somehow allude to "global or static object", where I would have thought that "real" acquire/release semantics should apply to all values.
Back to the question
On Windows, with Visual C++ (2005 - 2010), will declaring a (32bit? int?) variable as volatile
allow for atomic reads and writes to this variable -- or not?
What is especially important to me is that this should hold (or not) on Windows/VC++ independently of the processor or platform the program runs on. (That is, does it matter whether it's a WinXP/32bit or a Windows 2008R2/64bit running on Itanum2?)
Please back up your answer with verifiable information, links, test-cases!
lock
aroundvolatile
accesses, and that means that it will only be atomic if the underlying processor instruction would be atomic. I.e. it will not be for an unaligned integer type, or for a 64bit integer in a 32bit platform, for example. – Cathrinecathrynuint32_t
volatile
reference, accesses are not atomic. Note that the MSDN part that you quote does not say that it guarantees atomicity of the operation, it just says that the semantics it provides might be sufficient to be used for memory locks. I wish I had more time to write a full answer. – Cathrinecathrynuint64_t
for the operation not to be atomic. Intel/AMD guarantee atomicity of 32bit reads/writes in 32bit mode, and atomicity of 64bit reads/writes in 64bit mode. – Cathrinecathryn