[included comp.programming.threads]
Maybe. Sometimes.
Without the volatile, the result is undefined behavior.
Depending on the compiler and the processor, it might or it
might not work---changing the optimization level, or running on
a multi-core rather than a single core, make cause the behavior
to be different.
With the volatile, the result is implementation defined
behavior. A compiler may (but is not required to) define some
useful semantics for this case. Most compilers don't, at least
where multi-core systems are concerned. (I don't think that the
code in question will behave reliably on a multi-core system
even when compiled with VC++, at least through version 8.)
It means that MS compilers for PowerPC (e.g., XBOX), and
Itanium (e.g., Itanic) based platforms do indeed assign
significantly __overbearing!__ memory-barrier functionality to
their most "basic" meaning of the volatile keyword itself; by
default! ;^(... Volatile is implementation defined INDEED!
Basically, they assign heavy acquire-load membar semantics to
EVERY _naked_ load, and release-store semantics to EVERY
_naked_ store; this could be due to their relationship with
Intel I suppose. Keep in mind that Java does this as well for
programming "simplicity"; IMVHO, all of that crap is MAJOR
overkill and generates unneeded overheads on the memory
coherency system in general. Dumbs down things to a level that
makes things ridiculous.
I'm not really sure whether the intent of the example is to show
that (VC++ 8 didn't assign those semantics to volatile, at least
not on Intel architectures), or whether it isn't simple another
case of an author not knowing what he is writing about. I've
seen a lot of authors suggest something similar, with the
assumption that it was more or less portable, accross all
compilers.
I might add that a compiler which gives volatile such heavy
semantics doesn't bother me that much, since I never really use
volatile. On a Sparc, as far as I know, there is no way of
synchronizing memory access other than by using a membar
instruction---if volatile is to be used for memory mapped I/O
(it's original rationale), then the compiler must generate the
acquire-load or release-store member instructions.
They certainly do NOT have any real need to define volatile
such that it has anything to do with shared-memory threading.
IMO, using volatile and threading in then same sentence is
certainly misleading to say the least, and usually winds up
getting people to make erroneous assumptions about C/C++
compilers...
Very much agreed. Volatile was really designed for things that
don't behave like memory. Other mechanisms are necessary (and
being proposed) for threading.
I might add that the quality of the MSDN pages is very variable.
I often get the impression that they are written by someone who
doesn't really understand all of the technical issues---they
frequently neglect to give essential information, for example.
(Microsoft is not alone in this: a lot of documentation is
written by technical writers---with the accent on "writers".)