On 6/5/07, Brian Dessent <brian@xxxxxxxxxxx> wrote:
Trent Apted wrote: > static void* make_image() { > return new Image(); > } > > int main() { > static_cast<Event*>(make_image())->trigger(); > return 0; > } > > [...] > > Can anyone tell me what's going on? I think you're invoking undefined behavior because you can't use static_cast to downcast a pointer like that in the face of virtual inheritance. You have to use dynamic_cast. I don't really understand why you're intentionally obscuring things with the void* business,
A good point -- I had thought it necessary, as I am pushing things of type SDL_UserEvent into the SDL event queue -- a C interface, requiring void*. However, you've made me think about it and clued me in on a different strategy -- instead casting the Event* to a void* in the struct, I can convert some simpler struct to void* that just holds an Event* data member. Thanks! Although, I now have to create 2 objects for each event using new (unless I assume sizeof(EventHandle) == sizeof(void*) and do some reinterpret_cast ing). i.e. it becomes: static void* make_image() { EventHandle *eh = new EventHandle; eh->ref = new Image(); return eh; } int main() { static_cast<EventHandle*>(make_image())->ref->trigger(); return 0; } this seems to work.
but if you change it to "dynamic_cast<Event*>((Image *)make_image())->trigger()" you get the desired behavior.
Unfortunately, I can't do this, because the code that calls trigger() doesn't know anything about Image -- only Events (make_image is potentially any function that returns something derived from Event) -- and I can't dynamic_cast with a void*, until it has some info about a parent type.
The fact that the undefined behavior just happens to depend on the layout of Resource is incidental.
I had hoped virtual inheritance might remove the conflict between layout/order of the multiple bases. Indeed, it seems to, but only when there is a data member, which makes me think something else might be at work here.. A warning might also be nice -- "implicit cast to void* from type with virtual bases may cause undefined behaviour" -- but I thought I'd make sure I'm not missing something obvious before bugging the devs... *laments the hours spent debugging* ;-) - Trent.