strict aliasing (again)
Andrew Haley
aph@redhat.com
Tue Dec 2 11:52:00 GMT 2008
Mojmir Svoboda wrote:
> hello folks,
>
> i'm going through the code and trying to fix places where a 'dereferencing
> type-punned pointer...' appears. while trying to make it conformant i am
> trying to play with the code with type punning and try to see 'what if'.
>
> for example if i have code like this:
>
> template <typename T>
> struct ptr {
> T * m_ptr;
> ptr (T * p) : m_ptr(p) { }
>
> bool operator== (int rhs) const {
> return (*(int*) &m_ptr == rhs);
> }
> };
>
> and i am trying to find conditions under which this could produce wrong code...
> well this is my question: what are these conditions? what kind of unit test
> should i create?
The rule is simple: don't cast a pointer to an incompatible type and then
dereference the pointer.
> well this one seems to be easy to fix, but i'm getting my head dizzy from this:
>
> struct Vector3 {
> float x, y, z;
> float & operator[] (int i) { return *(&x+i); }
> };
This can't work. Well, unless i happens to be zero.
> this is simply terrible, i've never seen anything like that :) and i really
> don't know how should i fix this, because accesses are spread all around the
> code. easy way around at least the accesses would be something like:
>
> struct Vector3 {
> union {
> struct {
> float x, y, z;
> };
> float arr[3];
> };
> but there is apparently no such allowed construction.
That's right, there isn't.
> getting around the conversion (Vector3 + float) == Vector4 i really don't
> know: complete rewrite hangs in my mind..
>
> i'd really appreciate any thoughts on this.
What *are* you trying to do? There are straightforward ways to do this
such as
struct Vector3 {
float d[3];
float & x() { return d[0]; }
float & y() { return d[1]; }
...
};
Andrew.
More information about the Gcc-help
mailing list