Re: Crash in virtual method call
Re: Crash in virtual method call
- Subject: Re: Crash in virtual method call
- From: Brian Stern <email@hidden>
- Date: Thu, 12 Jun 2008 12:30:41 -0400
On Jun 12, 2008, at 4:04 AM, Doug Hill wrote:
Hey Jens,
Thanks for the MI tip. The class I'm working indeed uses Multiple
Inheritance with a moderately complex hierarchy.
Ah ha, so your example code in the first post wasn't representative.
I then tried switching the order of base classes in the derived
class declaration. For example, instead of:
class Derived : public Base1, public Base2 { ... };
I do
class Derived : public Base2, public Base1 { ... };
When I do this, the problem goes away! I can call all my methods
with no problem, including every method overridden from all base
classes. Not sure why this would fix the problem but things seem to
work now. I'll have to investigate this more as I really don't like
making changes that should have no effect to get code to work. I'm
guessing there's something else going on but it isn't obvious. The
only thing different about the two base classes is that one is pure
virtual and the other is not.
Did you mean virtual base class or pure virtual?
Is your inheritance hierarchy deeper than just the Base classes and a
single Derived layer? Sometimes in cases like this you need a double
typecast. Something like:
Base1* b = (Base1*) (Derived1*) aDerived2;
Think of the derived classes as structs placed one after another in
the inheritance hierarchy. In the case of diamond inheritance there
can be ambiguity of how the class should be laid out. Normally the
compiler knows all about this and correctly adjusts any pointers to
Derived to be the correct pointer to Base as needed without typecasts.
If the code uses typecasts then the compiler may not know that you're
really using a pointer to derived when it sees a pointer to Base1, for
instance. The double type cast can help the compiler to know the real
type of the pointer. Usually this kind of thing is only required if
the pointer is stored as a void*.
FWIW, this code comes from a Windows project that I'm porting, and
compiles and runs just fine using the Visual Studio C++ compiler.
While this doesn't necessarily prove anything it certainly is
interesting. Also, I'm unfortunately not in any position to modify
the class hierarchy as this is cross-platform code, so I have to get
it to work pretty much as is.
It's also possible that the code on Windows works by accident because
the layout of the Derived class is different for that compiler. It's
possible that the typecasts on Windows are there to work around a bug
in VC++ or a lack of understanding in the original author of the code.
Doug Hill
On Jun 11, 2008, at 9:14 PM, Jens Alfke wrote:
On 11 Jun '08, at 2:55 PM, Doug Hill wrote:
The method crashes because an input parameter passed to it comes
in as a bad pointer. Its pointer value is 4 less than the actual
passed in value.
Does your real code use multiple inheritance? You can run into
trouble like this with MI, where the 'this' pointer will be offset
by the runtime to point to where a secondary base class's instance
data begins. Doing type-casting of object pointers in the wrong way
can interfere with this and get the wrong offsets applied.
(If this is the case, I can't offer more detailed advice, as I've
always tried to stay as far away as possible from MI in C++ for
just these sorts of reasons...)
—Jens
--
Brian Stern
email@hidden
_______________________________________________
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