• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Crash in virtual method call
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Crash in virtual method call


  • Subject: Re: Crash in virtual method call
  • From: Doug Hill <email@hidden>
  • Date: Thu, 12 Jun 2008 15:07:31 -0700


On Jun 12, 2008, at 9:30 AM, Brian Stern wrote:
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.

Well, as I mentioned, I hadn't really been able to isolate the cause of the crash and was theorizing what could be the problem with the code I wrote up. Since I can't replicate the actual code I'm working with (for space and confidentiality reasons), I needed to come up with something more stripped down. For example, I'm using the Objective-C++ compiler to compile these files but adding this detail makes the write- up overly complicated. When I'm not sure what the problem is, I could be adding any number of unrelated details to my example that makes it needlessly hard to comprehend.


I tried to come up with a better example that more closely resembles my class architecture but I still couldn't reproduce the crash. But feel free to check this out if you like:

http://elasmobranch.com/TestProjects.zip

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?

Pure virtual. That is, the derived class needed to implement all the pure virtual methods of the base class. There are no virtual base classes.


Is your inheritance hierarchy deeper than just the Base classes and a single Derived layer?

Oh yes. :)

See my example in the link above for more details.

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*.

Well, I nowhere in my code are there casts to void*. And since I was using dynamic_cast to go from derived* to base* and it didn't return NULL, I have to assume that the compiler says this is a safe cast and produces a valid pointer. If dynamic_cast returns a valid pointer but it isn't a safe cast, I would assume this is a compiler bug. I shouldn't have to deal with strange casting to get it to work, right?


I think the bigger issue is why changing the order of base classes in the derived class declaration should have ANY effect. This would suggest:
- Improper casts.
- Some sort of compiler bug going on, but unfortunately I can't pin it down.


I haven't seen any improper casts yet, so I'm still trying to figure this out.

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.

Indeed, I was just throwing this fact out there. At no time have I ever relied upon the VC++ compiler producing code to be proof of anything about C++. In fact, in the course of this project, I've run across many examples of code that should not compile at all, that violates numerous parts of the C++ spec, but VC++ happily compiles away. I've thought of making up a list of these anomalies to look for in the future. :)


Thanks again for taking the time to give me feedback about this issue.

Doug Hill





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
  • Follow-Ups:
    • Re: Crash in virtual method call
      • From: Philip Aker <email@hidden>
References: 
 >Crash in virtual method call (From: Doug Hill <email@hidden>)
 >Re: Crash in virtual method call (From: Jens Alfke <email@hidden>)
 >Re: Crash in virtual method call (From: Doug Hill <email@hidden>)
 >Re: Crash in virtual method call (From: Brian Stern <email@hidden>)

  • Prev by Date: Re: Crash in virtual method call
  • Next by Date: Re: Compiler error when handling C++ std::string class variable
  • Previous by thread: Re: Crash in virtual method call
  • Next by thread: Re: Crash in virtual method call
  • Index(es):
    • Date
    • Thread