On Mar 21, 2:32 pm, Andy Venikov <swojchelo...@gmail.com> wrote:
Joshua Maurice wrote:
So is volatile sufficient - absolutely not. Portable? - hardly.
Is it necessary in certain cases - absolutely.
Perhaps I was a bit too strong in my statement. I did intent to say
"for portable uses".
However, for future reference, what compilers of what versions on what
platforms implement volatile with these semantics? I would like to
research these claims to be better prepared in this discussion and
future ones. Are any of these implementations not x86? These
implementations really don't provide a sane threading interface and
force the use of the volatile keyword for threading? Weird.
I'm sorry if I wasn't clear in my previous post, but I was talking about
standard volatile behavior.
The standard places a requirement on conforming implementations that:
1.9.6
The observable behavior of the abstract machine is its sequence of reads
and writes to volatile data and calls to library I/O functions
1.9.7
Accessing an object designated by a volatile lvalue (3.10), modifying an
object, calling a library I/O function, or calling a function that does
any of those operations are all side effects, which are changes in the
state of the execution environment. Evaluation of an expression might
produce side effects. At certain specified points in the execution
sequence called sequence points, all side effects of previous
evaluations shall be complete and no side effects of subsequent
evaluations shall have taken place
1.9.11
The least requirements on a conforming implementation are:
? At sequence points, volatile objects are stable in the sense that
previous evaluations are complete and
subsequent evaluations have not yet occurred.
That to me sounds like a complete enough requirement that compilers
don't perform optimizations that produce "surprising" results in so far
as observable behavior in an abstract (single-threaded) machine are
concerned. This requirement happens to be very useful for multi-threaded
programs that can augment volatile with hardware fences to produce
meaningful results.
That is one interpretation. Unfortunately / fortunately (?), that
interpretation is not the prevailing interpretation. Thus far in this
thread, we have members of the C++ standards committee or its
affiliates explicitly disagreeing on the committee's website with that
interpretation (linked else-thread). The POSIX standard explicitly
disagrees with your interpretation (see google). The
comp.programming.threads FAQ explicitly disagrees with you several
times (linked else-thread). We have gcc docs and implementation
disagreeing with your interpretation (see google). We have an official
blog from intel, the biggest maker of chips in the world, and a major
compiler writer, explicitly disagreeing with your interpretation
(linked else-thread). We have experts in the C++ community explicitly
disagreeing with your interpretation. (Thanks Andrei, and his paper "C+
+ And The Perils Of Double Checked Locking". Andy, have you even read
it?)
Basically, everyone in positions of authority are against you, from
the experts, the standards writers, and the implementation coders.
(Except for Microsoft Visual Studios, who actually make volatile reads
and writes like a mutex acquire and mutex release.) I don't know what
else I can do to dissuade you from this statement of fact concerning
the real world. As a practical matter, in the real world on real
implementations, volatile has no use as a correct, portable
synchronization primitive.
may loop forever.
necessary to get correct behaviour in multi-threaded designs. You don't
read of some state shared by more than one thread.
[ comp.lang.c++.moderated. First time posters: Do this! ]