Re: Crash in virtual method call
Re: Crash in virtual method call
- Subject: Re: Crash in virtual method call
- From: Doug Hill <email@hidden>
- Date: Thu, 12 Jun 2008 10:51:39 -0700
Thanks for the tip. I had indeed changed all the C-style casts to
dynamic_cast and it had not effect on the crashing behavior. My
understanding is that C-style casts are *potentially dangerous* if the
cast wouldn't succeed. For example, if dynamic_cast returned NULL.
However, dynamic_cast always returned the same pointer as the C-style
cast so I'm guessing the cast style wasn't the problem. Although,
again, dynamic_cast should always be used when down-casting to from a
derived* to base*. And yes, I think it was a little bit of laziness on
the part of the original implementor but there it is.
I'll have to try out the examples you all submitted to see what kind
of behavior results.
However, here's a link to some code that more closely mimics the class
hierarchy of part of my project. I tried to get as close to the same
hierarchy and usage as the classes that are causing me problems, but I
couldn't reproduce the crashing behavior. But you all seem to like
looking at code, so go at it. :)
http://elasmobranch.com/TestProjects.zip
FYI...You may need to make sym-links to the built frameworks in your
Frameworks folder (/User or /System/Library/) as I was a little lazy
to do all the work to copy the dependent frameworks into the main
application. Sorry but it was late last night.
Doug Hill
On Jun 12, 2008, at 10:25 AM, Paul Walmsley wrote:
Brady Duga wrote:
You should *never* be doing c-style casts of C++ objects,
especially when you have complex inheritance hierarchies. I am
guessing that the bug *does* exist under Windows, but just isn't
showing up due to variations in the compiler.
Indeed, C-style casts of C++ objects is evil and masks a number of
potentially serious bugs. I've experienced similar sorts of crashes
before in this kind of situation: you have classes Base and
Derived, then you want to pass a Derived object into a function that
takes a Base* :
void UseBase(Base* base) {...}
void DoSomething(Derived* d) {
UseBase(d);
}
Only the call to UseBase() results in a compiler warning: "can't
convert to type Base", or similar. The developer wonders why,
because he knows d can be converted to a Base pointer, so he becomes
a bit more forceful:
UseBase((Base*)d);
This stops the compiler from complaining, and all is great, or at
least it is until it crashes. The source of this problem is that
the cpp file doesn't include Derived.h, so it doesn't know that
Derived is related to Base. The cast then means 'reinterpret this
data as a different type of object' rather than 'walk the vtable to
get the interface pointer to Base', and you end up with bogus data
in your Base* object. In this example, #including Derived.h
allows the original version to build, and all is well.
So, check your code for occurrences of C-style casts and read item 2
of Scott Meyer's excellent More Effective C++ ('Prefer C++ style
casts').
Paul
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden