Strict pointer aliasing: is access through a '

2019-01-18 05:53发布

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.

2条回答
Anthone
2楼-- · 2019-01-18 06:21

Volatile can't help you avoid undefined behaviour here.

Well, anything regarding volatile is somewhat unclear in the standard. I mostly agreed with your answer, but now I would like to slightly disagree.

In order to understand what volatile means, the standard is not clear for most people, notably some compiler writers. It is better to think: when using volatile (and only when), C/C++ is pretty much high level assembly.

When writing to a volatile lvalue, the compiler will issue a STORE, or multiple STORE if one is not enough (volatile does not imply atomic).

When writing to a volatile lvalue, the compiler will issue a LOAD, or multiple LOAD if one is not enough.

Of course, where there is no explicit LOAD or STORE, the compiler will just issue instructions which imply a LOAD or STORE.

sellibitze gave the best solution: use memcpy for bit reinterpretations.

But if all accesses to a memory region are done with volatile lvalues, it is perfectly clear that the strict aliasing rules do not apply. This is the answer to your question.

查看更多
手持菜刀,她持情操
3楼-- · 2019-01-18 06:31

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).

查看更多
登录 后发表回答