zaheer
zaheer

Reputation: 3521

gcc thunk hack for multiple inheritance

I have a class X having derived from Y and Z (interface). An object of this class is passed to a library as void* which has access only to interface Z. [ The reason its not passed as Z* is there is an intermediate component that only accepts void*]

The layout of the the vtable with gcc thunks would be X, Y point to same address, however Z points to X + 8

So, i need to typecast the object as (Z *) (obj + 8) to get to Z. Is this safe, are there alternatives? I cant use RTTI.

Upvotes: 3

Views: 623

Answers (2)

rodrigo
rodrigo

Reputation: 98436

In this cases, just cast explicitly to the type you want to send with static_cast. It will take care of the details, as long as it knows both the type from/to it is converting.

That is:

X *theX = ...;
void *ptr = static_cast<Z*>(theX)

Then in the receiving code:

void *ptr = ...;
Z *theZ = static_cast<Z*>(ptr);

And if you know that it is actually an X:

X *theX = static_cast<X*>(theZ);

The bottom line is: whenever you cast a pointer into to void* and back, it should be converted to the very same type it was before.

Thus, this is undefined:

X *theX = ...;
void *ptr = static_cast<void*>(theX);
Z *theZ = static_cast<Z*>(ptr); //Undefined behavior!!!

Event though Z is a subclass of X, and a direct static_cast between the two would have worked.

Upvotes: 3

Juraj Blaho
Juraj Blaho

Reputation: 13461

No, casting (Z*)(obj + 8) is not safe.

Cast the object to Z* before casting to void*, then cast the void* back to Z*. That will be safe.

Upvotes: 2

Related Questions