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

Question on using volatile in a return type

0 views
Skip to first unread message

Ichthyostega

unread,
Dec 28, 2008, 6:59:29 PM12/28/08
to
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1


Hello all,

actually I am asking as well about semantics and best practices...


To start with, I am waiting on a condition variable (in a loop that is).
The actual condition is a bool flag located elsewhere, which is
to be passed in as a function parameter. So the correct type would be
"volatile bool&"

void func1 (volatile bool& flag) {
// init...

while (!flag && !err)
err = pthread_cond_wait (&cond, &mutex);

// ...
}


The "volatile" should give the compiler a hint not to employ optimisations
but fetch the value from the original location, where it may have been changed
by another thread meanwhile -- is this correct?

And: does the flag referred to have to be declared as volatile at the original
location? (usually somewhere in a class?). Or is it sufficient to define the
reference as volatile bool& ?


Now, assumed I want to use a functor instead of the bool flag.
What would be the correct and the "best" way to define it?

class Check1 {
bool operator() () { ... }
}

class Check2 {
volatile bool operator() () { ... }
}

class Check3 {
volatile bool& operator() () { ... }
}


My understanding is that for Check3 the "volatile" is necessary, is this
correct? But Check1 should be ok, because it's returning a value and it will
actually be re-invoked in each loop iteration?

And besides, would you consider the definition within Check2 good practice,
bad practice, expressive, superfluous, ....?


Thanks
Hermann Vosseler

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFJWBLhZbZrB6HelLIRAhvfAKDwT1b7f2sU0Mnfo6GhjCxWqUBA3QCgpzWq
Qiy/szkpY4lYukaqG7NqXPE=
=qzEq
-----END PGP SIGNATURE-----

peter koch

unread,
Dec 28, 2008, 7:09:21 PM12/28/08
to

Any use of volatile wrt threading is unneeded and bad practice (even
if you use a compiler where volatile has an established meaning
threadwise).

/Peter

Ichthyostega

unread,
Dec 28, 2008, 7:58:45 PM12/28/08
to
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

>> The "volatile" should give the compiler a hint not to employ optimisations

>> but fetch the value from the original location, where it may have been
>> changed by another thread meanwhile -- is this correct?

peter koch schrieb:


> Any use of volatile wrt threading is unneeded and bad practice (even if you
> use a compiler where volatile has an established meaning threadwise).
>

Hi Peter,

actually, your response confuses me somewhat. Could you please point me to
any resource explaining why this would be the case?

just to quote two:

http://www.ddj.com/cpp/184403766
http://blog.emptycrate.com/node/272

...which both seem to contradict your statement.
Probably I'm missing something very basic here?

Hermann

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFJWCDEZbZrB6HelLIRAsk0AJ44SkaHpt16o4Hd29NY4Aqjr80e2wCgpIsp
BcMTwvS4zpGEmuJsApnmTpo=
=UqZn
-----END PGP SIGNATURE-----

blargg

unread,
Dec 28, 2008, 9:31:52 PM12/28/08
to
Ichthyostega wrote:
[...]

> void func1 (volatile bool& flag) {
> // init...
>
> while (!flag && !err)
> err = pthread_cond_wait (&cond, &mutex);
>
> // ...
> }
>
> The "volatile" should give the compiler a hint not to employ
> optimisations but fetch the value from the original location, where
> it may have been changed by another thread meanwhile -- is this
> correct?

Correct. Like const, the const/volatile in references/pointers to
const/volatile affects what can be done via the reference/pointer.

int i;
const int& c = i;

c = 1; // error
i = 2; // OK

volatile int& v = i;
v = 1;
v = 2; // generate code must write to v twice
i = 3; // generated code can eliminate this write to i
i = 4;

> And: does the flag referred to have to be declared as volatile at
> the original location? (usually somewhere in a class?). Or is it
> sufficient to define the reference as volatile bool& ?

Original object can be non-volatile, just as with const.

> Now, assumed I want to use a functor instead of the bool flag.
> What would be the correct and the "best" way to define it?

To be equivalent, use volatile appropriately on any objects the
functor uses.

> class Check1 {
> bool operator() () { ... }
> }
>
> class Check2 {
> volatile bool operator() () { ... }
> }
>
> class Check3 {
> volatile bool& operator() () { ... }
> }
>
> My understanding is that for Check3 the "volatile" is necessary, is this
> correct? But Check1 should be ok, because it's returning a value and it will
> actually be re-invoked in each loop iteration?

Depends on what the ... is. Assuming something like

class Check1 {
volatile bool& b;
bool operator() () { return b; }
};

Then it's fine, since in accessing b the compiler is forced to read.
The same would work for the other two as well, with their unnecessary
volatile and bool.

If you instead had a reference-to-non-volatile,

class Check1 {
bool& b;
bool operator() () { return b; }
};

Check1 and Check2 could fail, since the compiler could avoid
re-reading the object referred to by b. But Check3 would work, since
the caller would be accessing the object via a volatile path:

class Check3 {
bool& b;
volatile bool& operator() () { return b; }
};

void func1 (Check3 flag)
{
while (!flag() && !err)
...
}

> And besides, would you consider the definition within Check2 good practice,
> bad practice, expressive, superfluous, ....?

From what little I know about multi-threaded (including multi-core and
multi-processor) coding, volatile alone is insufficient in most cases,
since in the absence of thread synchronization operations, the order
of memory writes in one thread can differ from the order they're seen
by another thread. That is, I believe that something like

volatile sig_atomic_t x, y;

void thread_1()
{
while ( x == 0 ) { }
cout << y;
}

void thread_2()
{
y = 1;
x = 1;
}

could print 0, even though thread_2 writes to y first (through a
volatile variable). What do you know, the example on Wikipedia is the
same: http://en.wikipedia.org/wiki/Memory_barrier

BTW, PGP-signing your messages adds lots of cruft that clutters your
postings.

Paavo Helde

unread,
Dec 29, 2008, 3:11:07 AM12/29/08
to
Ichthyostega <Ichthy...@web.de> kirjutas:

>
> peter koch schrieb:
>> Any use of volatile wrt threading is unneeded and bad practice (even
>> if you use a compiler where volatile has an established meaning
>> threadwise).

> actually, your response confuses me somewhat. Could you please point


> me to any resource explaining why this would be the case?
>
> just to quote two:
>
> http://www.ddj.com/cpp/184403766
> http://blog.emptycrate.com/node/272
>
> ...which both seem to contradict your statement.

The first one discusses how to recycle 'volatile' to do some compile-time
checks. The second is a negative and non-portable example, as the author
admits in the end of the page.

'volatile' is needed for programming memory-mapped peripheral devices. If
you don't do this, you can forget about volatile! This topic has been
covered here many times.

Paavo

James Kanze

unread,
Dec 29, 2008, 5:17:26 AM12/29/08
to
On Dec 29, 12:59 am, Ichthyostega <Ichthyost...@web.de> wrote:
> actually I am asking as well about semantics and best practices...

> To start with, I am waiting on a condition variable (in a loop
> that is). The actual condition is a bool flag located
> elsewhere, which is to be passed in as a function parameter.
> So the correct type would be "volatile bool&"

> void func1 (volatile bool& flag) {
> // init...

> while (!flag && !err)
> err = pthread_cond_wait (&cond, &mutex);
> // ...
> }

> The "volatile" should give the compiler a hint not to employ
> optimisations but fetch the value from the original location,
> where it may have been changed by another thread meanwhile --
> is this correct?

Formally, the meaning of "volatile" is largely implementation
dependent; the standard waffles a bit about "access", but
doesn't say what it means by an access (and the C standard says
explicitly: "What constitutes an access to an object that has
volatile-qualified type is implementation-defined.") In
practice, the compilers I know (Sun CC, g++ and VC++) don't
define it to be anything useful.

If you're waiting on a conditional variable, of course, you
don't need volatile, because all necessary synchronization has
been provided by the system requests (e.g. pthread_cond_wait,
pthread_cond_signal and pthread_cond_broadcast under Posix).

> And: does the flag referred to have to be declared as volatile
> at the original location? (usually somewhere in a class?). Or
> is it sufficient to define the reference as volatile bool& ?

Volatile generally isn't relevant to threading. You don't need
it anywhere. (At least for the systems I'm familiar with: Posix
and Windows. A system certainly could define its threading
primitives in a way that made volatile relevant, and require
that compilers implement it in a corresponding way.)

--
James Kanze (GABI Software) email:james...@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

0 new messages