Article View: gnu.g++.bug
Article #114MI/virtual base class bug
From: Paul Vaughan
Date: Tue, 07 Apr 1992 20:58
Date: Tue, 07 Apr 1992 20:58
170 lines
4690 bytes
4690 bytes
The following program produces incorrect output when compiled with
SUN4, g++ 2.1 latest patches
DecStation 3100 g++ 2.1 only one patch (by Tiemann)
SUN4 cfront 2.1 from ObjectCenter
but produces correct output when compiled with
SUN4 g++ 1.37.2
The symptom for g++ 2.1 is that when calling a function declared on a
virtual base class and redefined on the second base of a multiply
inherited class, the incorrect offset is applied, so that the this
object points into the wrong part of the object as the method
executes.
Cfront does the same thing, but only when the virtual function is
called using a pointer to the virtual base class.
----------------------------------------------------------------
#include <stream.h>
class Entity {
public:
Entity() { cout << (int) this << " Entity::Entity()\n"; };
virtual ~Entity() { cout << (int) this << "~Entity::Entity()\n"; }
virtual void Name() { cout << (int) this << " Entity::Name()\n"; };
};
class A : virtual public Entity {
public:
A() { cout << (int) this << " A::A()\n"; };
~A() {cout << (int) this << "~A::A()\n";}
void Name() { cout << (int) this << " A::Name()\n"; }
};
class At : public A {
public:
At() { cout << (int) this << " At::At()\n"; }
~At() { cout << (int) this << "~At::At()\n"; }
};
class B : virtual public Entity {
public:
B() { cout << (int) this << " B::B()\n"; }
~B() { cout << (int) this << "~B::B()\n"; }
};
class Bt : public B {
public:
Bt() { cout << (int) this << " Bt::Bt()\n"; }
~Bt() { cout << (int) this << "~Bt::Bt()\n";}
};
class BtAt : public Bt, public At {
public:
BtAt() { cout << (int) this << " BtAt::BtAt()\n"; }
~BtAt() {cout << (int) this << "~BtAt::BtAt()\n";}
};
class BtAtderived : public BtAt {
public:
BtAtderived() { cout << (int) this << " BtAtderived::BtAtderived()\n"; }
~BtAtderived() {cout << (int) this << "~BtAtderived::BtAtderived()\n";}
};
main() {
BtAtderived* btatderived = new BtAtderived;
cout << "\n";
cout << "btatderived->Name()\n";
btatderived->Name();
cout << "\n\n";
cout << "((Entity*) btatderived)->Name()\n";
((Entity*) btatderived)->Name();
cout << "\n\n";
delete btatderived;
}
----------------------------------------------------------------
Here is the incorrect output generated when compiled with g++ 2.1,
both patched and unpatched. I've annotated the output with comments to
point out the pertinent lines.
[3.89]suntrek) atbug
36624 Entity::Entity()
36616 B::B()
36616 Bt::Bt()
36620 A::A() // address for A object
36620 At::At()
36616 BtAt::BtAt()
36616 BtAtderived::BtAtderived()
btatderived->Name()
36616 A::Name() // does not match address for A object WRONG
((Entity*) btatderived)->Name()
36616 A::Name() // does not match address for A object WRONG
36616~BtAtderived::BtAtderived()
36616~BtAt::BtAt()
36620~At::At()
36620~A::A()
36616~Bt::Bt()
36616~B::B()
36624~Entity::Entity()
Here is the incorrect output generated when compiled by cfront 2.1
(from ObjectCenter).
27812 Entity::Entity()
27792 B::B()
27792 Bt::Bt()
27800 A::A()
27800 At::At()
27792 BtAt::BtAt()
27792 BtAtderived::BtAtderived()
btatderived->Name()
27800 A::Name() // fine when called from a BtAtderived*
((Entity*) btatderived)->Name()
27792 A::Name() // fails when called from an Entity* WRONG
27792~BtAtderived::BtAtderived()
27792~BtAt::BtAt()
27800~At::At()
27800~A::A()
27792~Bt::Bt()
27792~B::B()
27812~Entity::Entity()
Here is the correct output generated by g++-1.37.2
[2.115]sunspot) !a
atbug
140048 Entity::Entity()
140040 B::B()
140040 Bt::Bt()
140044 A::A()
140044 At::At()
140040 BtAt::BtAt()
140040 BtAtderived::BtAtderived()
btatderived->Name()
140044 A::Name() // matches address for A object
((Entity*) btatderived)->Name()
140044 A::Name() // matches address for A object
140040~BtAtderived::BtAtderived()
140040~BtAt::BtAt()
140044~At::At()
140044~A::A()
140040~Bt::Bt()
140040~B::B()
140048~Entity::Entity()
Paul Vaughan
Technical Details
Message-ID:
<9204072058.AA15620@bock.cad.mcc.com>Path:
arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!CAD.MCC.COM!vaughanShow Full Headers
Complete Article Headers
Newsgroups: gnu.g++.bug Path: arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!CAD.MCC.COM!vaughan From: vaughan@CAD.MCC.COM (Paul Vaughan) Subject: MI/virtual base class bug Message-ID: <9204072058.AA15620@bock.cad.mcc.com> Sender: gnulists@ai.mit.edu Organization: GNUs Not Usenet Distribution: gnu Date: Tue, 7 Apr 1992 20:58:23 GMT Approved: bug-g++@prep.ai.mit.edu Lines: 171