Re: Share .cpp and .h along projects
Ben Voigt [C++ MVP] wrote:
"Doug Harrison [MVP]" <dsh@mvps.org> wrote in message
news:nefcc3hh5er85j8hdrklli59i553ve10tu@4ax.com...
On Fri, 17 Aug 2007 15:14:50 -0500, "Ben Voigt [C++ MVP]"
<rbv@nospam.nospam> wrote:
volatile std::vector* g_sharedVector;
[...]
BTW, why _exactly_ did you use volatile in your declaration of
g_sharedVector? (Based on the declaration of
InterlockedExchangePointerAcquire, it shouldn't even compile.)
C'mon, it's an oversight coming from not consistently putting the
CV-qualifiers to the right of what they affect. I'm pretty sure you
understood what he meant and that he didn't actually compile the code.
Here, let me show you a variant of your code that is going to fail
with an intelligent compiler, no peering into the DLL necessary:
namespace {
// assume the address of x is never taken
int x; // needs to be volatile
mutex mx;
}
// None of these touch x.
void lock(mutex&);
void unlock(mutex&);
void g(int);
void f1()
{
lock(mx);
g(x);
unlock(mx);
lock(mx);
g(x);
unlock(mx);
}
void f2()
{
lock(mx);
++x;
unlock(mx);
}
As you stated "A compiler that can see into all these functions will
observe that none of lock, unlock, and g access x, so it can cache the
value of x across the mutex calls in f1." I tell you that because x has
file-local linkage and the address of x is not taken, aliasing analysis
in current compilers proves that none of lock, unlock, or g access x --
without seeing into the functions.
Right, but it knows that lock and unlock are functions that affect
multithreading behaviour not only in that they lock a mutex but also that
they present a memory barrier (well, at least according to POSIX) and that
it must not cache the value of 'x' for that reason. Seriously,
multithreading is simply not possible without compiler support, it must
know that some code can be called in a multithreaded context.
Further, it knows that 'f1'/'f2' can be called by multiple threads at once,
so again it can't perform optimisations that affect 'x'.
Using DLLs to inhibit optimization is broken, Broken, BROKEN!
Thinking that multithreading problems can be fixed by inhibiting any
optimisations is broken. However, when a call goes into a DLL the compiler
must assume (as long as it can't inspect the content) that it could present
a memory barrier.
Adding "volatile" to the declaration of x fixes the problem.
No, sorry. Firstly, the definition of 'volatile' is too vague to be of any
use in (MT) programming - you read the discussions on cpt and know that its
meaning is mostly compiler-dependant. Secondly, you already have (almost
explicit) memory barriers there from the lock/unlock calls, these are
really enough.
Note that if that wasn't enough, you would have to apply a 'volatile'
qualifier to the whole vector, too, i.e. all the pointers it contains and
even the pointers contained by its elements.
Uli