strict aliasing (again)

John Fine johnsfine@verizon.net
Tue Dec 2 16:47:00 GMT 2008


Mojmir Svoboda wrote:
>     struct some_base {
>         virtual int id () = 0;
>     };
>     struct bar : some_base { int id () { return 1; } };
>     void foo (int id) { }
>     #define REG(aa) foo(((aa*)0L)->aa::id())
>
> is that code harmless from your viewpoint? actually, how come the code emitted
> works at all? :)
>
>   
One thing I often find annoying in C++ is that you can't have virtual 
static functions (a function that can be selected using an object's 
virtual function table but then doesn't take that object as an implicit 
"this" parameter).

It appears that id() in your class hierarchy is such a function.  It is 
virtual and thus typically needs an object for selection, but that can 
be overridden, as it is in your example with a::.  As a virtual 
function, it needs a "this" pointer, but as it doesn't actually use its 
"this" pointer, it doesn't need to be a valid "this" pointer.

I'm not 100% sure the behavior is undefined.  I think it is undefined.  
I also think it is "harmless".  If a member function doesn't implicitly 
or explicitly use the "this" compiler (which I'm assuming is the case in 
your example), I think the C++ standard would allow the compiler to 
throw in some pointless access through "this", but I'm sure an actual 
compiler wouldn't.
> for you perhaps it's evident, but being an user i have to rely on standard.
> if standard says that's an undefined or implementation defined behaviour than
> i'd rather kick this code out.
>   
If you need to rely on the standard, I expect you need to throw out the 
whole mess of code and rewrite from scratch with a decent design.  I 
assume you don't have time to do that. Welcome to the real world and 
sorry the standard couldn't make that journey with you.

> you mean "does not violate" from the viewpoint of optimizer, do you?
> and what if you later take address of the returned reference from GetVector3()
> and work with that, still ok?
>   

That address is still OK.  For aliasing issues, what matters is actual 
accesses to types that can be actually accessed in the underlying 
architecture.  I'm not 100% comfortable with what the compiler might do 
with the implicitly defined assignment operator on Vector3 reading from 
the reference returned by GetVector3().  I think it's OK, but hard to be 
sure.

It sounds like you can more easily tweak the definition of Vector4 than 
all the references to it.  Why not make Vector3 a public base class of 
Vector4 (then the only extra member of Vector4 is w).  That doesn't 
correct all the undefined behavior, but it corrects a bunch of it.





More information about the Gcc-help mailing list