Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

volatile-qualified primitive types

51 views
Skip to first unread message

Christopher D. Russell

unread,
Mar 17, 2005, 3:18:08 AM3/17/05
to
Hello,

I'm reading the Alexandrescu article "Generic<Programming>: volatile -
Multithreaded Programmer's Best Friend Volatile-Correctness or How to Have
Your Compiler Detect Race Conditions for You"
(http://www.cuj.com/documents/s=7998/cujcexp1902alexandr/) - an excellent
expose on the volatile qualifier. However, for the life of me, I can't figure
out how to volatile-qualify a primitive type so that the compiler emits an
error (or warning even) if I operate on the variable without const_cast.

Alexandrescu writes "Simply encapsulate the primitive data that you use in
higher-level structures and use volatile with those structures.
Paradoxically, it's worse to use volatile directly with built-ins, in spite
of the fact that initially this was the usage intent of volatile!"

So I tried this:

template <typename PrimitiveT> class PrimitiveWrapper
{
private: // disallow default construction
PrimitiveWrapper() {}

public: // construction/destruction
PrimitiveWrapper(PrimitiveT const& _Primitive) : Primitive(_Primitive) {}
~PrimitiveWrapper() {}

public: // implementation
PrimitiveT Primitive;

};

.... The idea is that I should be able to, for example, declare a volatile
PrimitiveWrapper<int> as opposed to a volatile int in order to get the
compiler to emit an error if I attempt to access its Primitive member sans
const_cast. No luck however. Even volatile-qualify the declaration of
Primitive in my wrapper seems to make no difference.

Would someone please suggest a way that I can accomplish this task. The
corollary question is why on earth is this standard behavior? I'm sure
there's some good reason (there always is). But it's not at all obvious to me
what it is.

Any assistance is appreciated.

- Regards
Chris


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Andrei Alexandrescu (See Website for Email)

unread,
Mar 18, 2005, 8:12:22 AM3/18/05
to
Christopher D. Russell wrote:
> Hello,
>
> I'm reading the Alexandrescu article "Generic<Programming>: volatile -
> Multithreaded Programmer's Best Friend Volatile-Correctness or How to Have
> Your Compiler Detect Race Conditions for You"
> (http://www.cuj.com/documents/s=7998/cujcexp1902alexandr/) - an excellent
> expose on the volatile qualifier.

Thanks. You should be aware, however, that the introductive example on
volatile's role is mistaken, which has led many to misunderstand the
article and think it relies on some specific semantics of volatile. To
see why, you may want to check:

http://moderncppdesign.com/publications/DDJ_Jul_Aug_2004_revised.pdf

> However, for the life of me, I can't figure
> out how to volatile-qualify a primitive type so that the compiler emits an
> error (or warning even) if I operate on the variable without const_cast.
>
> Alexandrescu writes "Simply encapsulate the primitive data that you use in
> higher-level structures and use volatile with those structures.
> Paradoxically, it's worse to use volatile directly with built-ins, in spite
> of the fact that initially this was the usage intent of volatile!"
>
> So I tried this:
>
> template <typename PrimitiveT> class PrimitiveWrapper
> {
> private: // disallow default construction
> PrimitiveWrapper() {}
>
> public: // construction/destruction
> PrimitiveWrapper(PrimitiveT const& _Primitive) : Primitive(_Primitive) {}
> ~PrimitiveWrapper() {}
>
> public: // implementation
> PrimitiveT Primitive;
>
> };
>
> .... The idea is that I should be able to, for example, declare a volatile
> PrimitiveWrapper<int> as opposed to a volatile int in order to get the
> compiler to emit an error if I attempt to access its Primitive member sans
> const_cast. No luck however. Even volatile-qualify the declaration of
> Primitive in my wrapper seems to make no difference.

This is just a simple error. When you encapsulate data, you must as a
matter of course make that data private and make it accessible via
functions only. Otherwise, no matter how you play the
constructors/destructors game, client code that accesses that data will
bypass all of your fortress.


Andrei

Christopher D. Russell

unread,
Mar 19, 2005, 5:37:54 AM3/19/05
to
[ In reference to: http://tinyurl.com/6htof ]

Andrei, thank you for the response.

> ... When you encapsulate data, you must as a


> matter of course make that data private and make it accessible via
> functions only. Otherwise, no matter how you play the
> constructors/destructors game, client code that accesses that data will
> bypass all of your fortress.

Okay. That's clear enough. I was hoping I missed something that would allow
me to accomplish this without resorting to access methods and private data.
Oh well. Expressing my code so that others don't necessarily have to
understand the nuances of the threading model is more important than elegance
and performance in the grand scheme of things.

The cited article
http://moderncppdesign.com/publications/DDJ_Jul_Aug_2004_revised.pdf was
very illuminating. In 10 [Sidebar] volatile: A Brief History, you discuss the
more restrictive semantics imposed on the volatile concept by Java and .NET
CLI and conclude by stating "We know of no similar work being done on C's or
C++'s volatile."

Maybe this is because most people are like I was a few days ago - blissfully
unaware of the incorrectness of their multithreaded code and ignorant of the
complexities of fixing it? Generalizing the notion of "abstract machine" to
multiple threads and multiple processors is truly daunting. Still, given that
multiple core processors and SMP machines are more and more common, I'm
surprised to learn that it's not a front burner issue in the C++ community.
The ability to succinctly and portably express concurrency seems _so_ vital.

It sure would be nice to have standard language support for something
syntactically similar to namespaces that could be used to (a) preserve
sequence ordering for a block of statements (b) explicitly express cache
coherency constraints. Maybe someday.

- Thanks again and regards

Chris Russell
http://encapsule.com // http://hyperworx.org // http://chrisrussell.net

Andrei Alexandrescu (See Website For Email)

unread,
Mar 20, 2005, 6:38:46 PM3/20/05
to
> The cited article
> http://moderncppdesign.com/publications/DDJ_Jul_Aug_2004_revised.pdf was
> very illuminating. In 10 [Sidebar] volatile: A Brief History, you discuss the
> more restrictive semantics imposed on the volatile concept by Java and .NET
> CLI and conclude by stating "We know of no similar work being done on C's or
> C++'s volatile."
>
> Maybe this is because most people are like I was a few days ago - blissfully
> unaware of the incorrectness of their multithreaded code and ignorant of the
> complexities of fixing it? Generalizing the notion of "abstract machine" to
> multiple threads and multiple processors is truly daunting. Still, given that
> multiple core processors and SMP machines are more and more common, I'm
> surprised to learn that it's not a front burner issue in the C++ community.
> The ability to succinctly and portably express concurrency seems _so_ vital.

Fortunately, there are good news. Just like you, seeing that
(astonishingly) nobody seemed to consider that adding threading support
to C++ is vital for the community and for the survival of the language
itself, yours truly has decided to spur an effort in negative time and
to convince a small team of experts (notably Hans Boehm) to contribute:

http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2004/n1680.pdf
http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1777.pdf

Andrei

0 new messages