Re: Share .cpp and .h along projects
"Doug Harrison [MVP]" <dsh@mvps.org> wrote in message
news:p7r8c399sc57e5k24cj0t36qmn6ocpvc80@4ax.com...
On Thu, 16 Aug 2007 08:41:35 -0500, "Ben Voigt [C++ MVP]"
<rbv@nospam.nospam> wrote:
That is exactly what "volatile" does. Even in old versions of the
compiler,
when memory barriers are not used, volatile exactly prevents the
optimization you are speaking of, in a way that is not fragile to moving
source files between DLLs, changing optimization settings, etc.
Provided that "lock" and "unlock" trigger memory barriers, the code you
show
will be correct on any version of the C++ compiler (even non-Microsoft
compilers), using any optimization settings, if you would only say
"volatile
int x".
You can't require people to use volatile on top of synchronization.
Synchronization needs to be sufficient all by itself, and it is in any
compiler useful for multithreaded programming.
1. You're not thinking this through. Make x a vector<int>, and then what?
Cast volatile away so you can call its member functions? More generally,
how do you take existing code and use it in a thread-safe way?
Only single machine words can be used for interlocked operations, but any
larger object can be controlled in a threadsafe manner using a volatile
pointer (which is word-sized) and memory barriers.
2. Using volatile can be a huge performance killer, because it suppresses
optimization inside critical sections, where it's perfectly fine to use.
3. Reading and writing a volatile variable is ordered only WRT reading and
writing other volatile variables and other observable behavior, so what
you're proposing requires pretty much everything to be volatile.
"other observable behavior" covers a lot of things.
All you need is synchronization.
Synchronization is defined using volatile primitives.
In fact, if your "x" is in a anonymous namespace, which would be the
recommended practice, and you do not take its address, then the compiler
aliasing analysis can determine that it will not be touched by the
"opaque"
DLL, and reorder or remove the access to x once again.
That optimization is not safe for a compiler useful for multithreaded
programming. Note that I didn't say "touched" by the DLL; I said
"reachable" from the DLL. The difference is, the compiler would have to
prove no potential code path in a MT program accesses the variable, which
is quite a tall order.
Compiler optimizations (and CPU reorders) are always defined in terms of
equivalence on a single sequence of execution.