Re: Share .cpp and .h along projects
"Doug Harrison [MVP]" <dsh@mvps.org> wrote in message
news:va49d3hm62f07nrid2oifl9md3fi0kb955@4ax.com...
On Tue, 28 Aug 2007 12:38:48 -0500, "Ben Voigt [C++ MVP]"
<rbv@nospam.nospam> wrote:
It's "volatile-correctness" and prevents the object from being passed
someplace it shouldn't, just like const-correctness does:
class Example
{
char myarray[1000];
void doit() const
{
sprintf(myarray, "%d", 5);
}
};
Because myarray is a pointer-to-const inside a const member function
the compiler stops me from using it as the first argument to sprintf,
overwriting the data and breaking the "const" contract.
To be faithful to what you have been claiming, you should have used a
pointer, not an array. The "corrected" version of your example uses a
volatile pointer, not a pointer-to-volatile:
std::vector* volatile g_sharedVector;
This is perfectly fine:
std::vector* p = g_sharedVector;
Doesn't give you much "protection".
There's a guarantee that the actual value of g_sharedVector will be used,
not a cached value. But if you read what I said, it was that
(&g_sharedVector) could not be passed to a function not designed for
volatile access.
Similarly, because g_sharedVector is declared volatile, taking its address
yields a pointer-to-volatile, which the compiler will not permit to be
passed to a function that accepts a pointer to non-volatile.
Interlocked***
can work on non-volatile variables, but volatile variables cannot be used
by
anything but Interlocked*** and other functions designed for
synchronization. Just like non-const variables can be read, but marking a
variable as const means that it can only be read.
The only important thing in all this is your use of InterlockedXXX, which
allowed you to poorly imitate a mutex. Since you admit that InterlockedXXX
"can work on non-volatile variables", would you like to amend your earlier
claim:
any larger object can be controlled in a threadsafe
manner using a volatile pointer (which is word-sized) and memory barriers.
An accurate statement would be:
"It is possible to poorly emulate a mutex using pointers and
InterlockedExchangePointer."
However, you've been arguing the necessity of using volatile when
programming with mutexes, or as I sometimes call it, "volatile on top of
synchronization". I hope you understand now that volatile is not even
necessary for the correct operation of your example.
The release part of the operation was able to use a volatile write in VC2005
and avoid the function call. That wouldn't be correct without volatile.