Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!sdd.hp.com!spool.mu.edu!cs.umn.edu!kulkarni From: kulkarni@cs.umn.edu ( Srinivas R. Kulkarni kulkarni@umn-cs.cs.umn.edu) Newsgroups: comp.lang.c++ Subject: Multiple Inheritance Problem Keywords: multiple-inheritance, c++, virtual functions Message-ID: <1991Jun27.151344.458@cs.umn.edu> Date: 27 Jun 91 15:13:44 GMT Organization: University of Minnesota, Minneapolis, CSci dept. Lines: 168 piero@bnrmtl.bnr.ca (Piero Colagrosso) writes: > > I have been experiencing a problem with the use of multiple > inheritance in C++. I am using the Sun (AT&T) compiler on a Sun >... > The result: It seems that the calculation of the "this" pointer > which is passed to m1 (i.e.e C::m1 is done incorrectly, resulting in > defective code (an unexpected crash was the original symptom >...( scrumpy@.1991Jun19.104037.13020 ) We have observed a similar syndrome. Unfortunately, the resultant code isn't always kind enough to crash--in our case it quietly returns the wrong answer! What's curious is that it seems to handle the simple cases but fails on a slightly more complex one. Here is the (simplified) situation in which we have observed the problem. The classes are A, B, C and AA, BB, and CC. Methods m1, m2, and m3 with implementations on classes as indicated by '...'. All inheritance links are 'virtual', as are all method declarations. A...m1 /| / | m1...AA B...m2 | /| |/ | m2...BB C...m3 | / |/ m3...CC An instance *cc of CC is created and we invoke m1, m2, and m3 on it with the expected results as indicated by the trace and returned state information. The pointer cc is cast to a pointer *c of C, and the same methods are invoked. The correct _functions_ are entered in each case, but the "this" pointer is wrong in the case of m1, while it is correct in the cases of m2 and m3. Help! --------------------------------------------------------------------------- #include class A { public: virtual int m1( void ); }; class B : public virtual A { public: virtual int m2( void ); }; class C : public virtual B { public: virtual int m3(void ); }; A::m1( void ) { cout << "\ninvoking virtual A::m1 for object " << this << ": "; return 0; } B::m2( void ) { cout << "\ninvoking virtual B::m2 for object " << this << ": "; return 0; } C::m3( void ) { cout << "\ninvoking virtual C::m3 for object " << this << ": "; return 0; } class AA : public virtual A { public: int Avar; virtual int m1( void ); }; class BB : public virtual AA, public virtual B { public: int Bvar; virtual int m2( void ); }; class CC : public virtual BB, public virtual C { public: int Cvar; virtual int m3( void ); }; AA::m1(void) { cout << " Invoke AA.m1 on object " << this << ": "; return Avar; } BB::m2(void) { cout << " Invoke BB.m2 on object " << this << ": "; return Bvar; } CC::m3(void) { cout << " Invoke CC.m3 on object " << this << ": "; return Cvar; } main() { C *c; CC* cc = new CC; cc->Avar = 1; cc->Bvar = 2; cc->Cvar = 3; cout << "\n cc->m1(): " << cc->m1(); cout << "\n cc->m2(): " << cc->m2(); cout << "\n cc->m3(): " << cc->m3(); c = cc; // cast it cout << "\n\nCast CC to C\n"; cout << "\n c->m1(): " << c->m1(); cout << "\n c->m2(): " << c->m2(); cout << "\n c->m3(): " << c->m3() << "\n"; } --------------------------------------------------------------------------- Sample output: cc->m1(): Invoke AA.m1 on object 0x6614: 1 <<<-- desired result cc->m2(): Invoke BB.m2 on object 0x65f4: 2 cc->m3(): Invoke CC.m3 on object 0x65d8: 3 Cast CC to C c->m1(): Invoke AA.m1 on object 0x65f4: 2 <<<-- should be as above c->m2(): Invoke BB.m2 on object 0x65f4: 2 c->m3(): Invoke CC.m3 on object 0x65d8: 3 --------------------------------------------------------------------------- We are using a Sparc 1+ with the Sun (AT&T) Compiler 2.1 and SunOS 4.1.1. The code seems (from my understanding of the language) to be legal; certainly, the compiler does not issue even a peep of a warning message. Nonetheless, the results are disasterously wrong. Any explanations/workarounds/sympathy would be greatly appreciated. Please e-mail responses to: kulkarni@umn-cs.cs.umn.edu or harp@ssdc.honeywell.com