[comp.sys.mac.programmer] multiple inheritance bug

lars@island.COM (Lars Nyman) (02/05/91)

I have a problem with multiple inheritance using virtual base classes, and
suspect it's a bug in the C++ compiler.

Three level hierarchy: Base, Derived, MostDerived.

class Base { ... }
class Derived : virtual Base { ... }
class MostDerived : Derived, Mixin { ... }

The problem occurs when executing inside Derived's constructor.   If
Derived() calls a function in Base, which in turns calls a virtual 
function implemented in Derived, the 'this' pointer will be incorrect
(see below code for more technical info).
Basically, makes it impossible to use multiple inheritance...

I have tested it under Sun C++ 2.0 and MPW C++ 3.1, both which are 
based on CFront 2.0.

Is this fixed in CFront 2.1 ?
Can somebody who have a C++ implementation based on CFront > 2.0 check
whether the same problem exist ?

// ---------- Begin Code --------------

#include <iostream.h>

class Shape {
 public:
    Shape() { cout << "Created Shape: " << (unsigned long) this << "\n"; }
    
    virtual void moveTo(int) { draw(); }
    virtual void draw() = 0;
};

class Circle : virtual public Shape {
 public:
    Circle() { moveTo(0); }

    void draw()
    {
	cout << "Circle drawing Shape: " << (unsigned long) (Shape *) this << "\n";
    }
};

class SomeMixin {
    char data[256];
};

class RedCircle : public Circle, public SomeMixin {
 public:
    RedCircle() { moveTo(0); }
    void draw()
    {
	cout << "RedCircle drawing Shape: " << (unsigned long) (Shape *) this << "\n";
    }
};


void main()
{
    cout << "********* Circle ***********\n";
    Circle c;

    cout << "********* RedCircle ********\n";
    RedCircle rc;
}

// -------------- End Code ---------------


When Circle is being constructed, it installs a vtbl for Shape.  However,
the vtbl Circle installs contains offsets as if Shape was part of a "pure"
Circle.  Thus, if a "pure" Circle is being constructed things work fine.
But, if the Circle being constructed is a part of something else, e.g. a 
RedCircle, which have multiple base classes, then the vtbl Circle installs
in its constructor for Shape is incorrect.

The vtbl Circle installs for Shape should be contain the same offsets
as the vtbl RedCircle installs for Shape in RedCircle's constructor,
but the vtbl should not contain the same functions as the vtbl RedCircle
installs (since when Circle's constructor is executing the object is
not yet a RedCircle).