Reputation: 3521
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
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
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