views:

140

answers:

1

On the heels of a specific problem, a self-answer and comments to it, I'd like to understand if it is a proper solution, workaround/hack or just plain wrong.

Specifically, I rewrote code:

T x = ...;
if (*reinterpret_cast <int*> (&x) == 0)
  ...

As:

T x = ...;
if (*reinterpret_cast <volatile int*> (&x) == 0)
  ...

with a volatile qualifier to the pointer.

Let's just assume that treating T as int in my situation makes sense. Does this accessing through a volatile reference solve pointer aliasing problem?

For a reference, from specification:

[ Note: volatile is a hint to the implementation to avoid aggressive optimization involving the object because the value of the object might be changed by means undetectable by an implementation. See 1.9 for detailed semantics. In general, the semantics of volatile are intended to be the same in C++ as they are in C. — end note ]

EDIT:

The above code did solve my problem at least on GCC 4.5.

+8  A: 

Volatile can't help you avoid undefined behaviour here. So, if it works for you with GCC it's luck.

Let's assume T is a POD. Then, the proper way to do this is

T x = …;
int i;
memcpy(&i,&x,sizeof i);
if (i==0)
  …

There! No strict aliasing problem and no memory alignment problem. GCC even handles memcpy as an intrinsic function (no function call is inserted in this case).

sellibitze
"Volatile can't help you avoid undefined behaviour here" — why? Do you have any source for this statement?
doublep
C++ standard, section 3.10 paragraph 15 is the place you need to look at with respect to strict aliasing. There's no mention of an exception involving volatile.
sellibitze
There are cases where it's not undefined behavior. For example `struct A { int a; }; int main() { X x; *reinterpret_cast<int*>( }` is fine and perfectly defined according to `9.2/17`. The object is of type `int`, and the lvalue is also of type `volatile int`, thus the aliasing goes fine.
Johannes Schaub - litb
@Johannes: In my case `T` could be anything, only the size matches `int`. E.g. a pointer on many platforms will do.
doublep
@Johannes: I didn't mean to imply that it's always undefined behaviour. I just meant to say that volatile won't make any difference with respect to 3.10/15.
sellibitze
@sellibitze, ah that makes sense now. Somehow i missed the "Does this accessing through a volatile reference solve pointer aliasing problem?" part :) thanks
Johannes Schaub - litb