From mboxrd@z Thu Jan 1 00:00:00 1970 From: gbr@netel.bg To: gcc-gnats@gcc.gnu.org Subject: c++/3608: Virtual funtions called with wrong this pointer when having virtual inheritance Date: Sun, 08 Jul 2001 06:56:00 -0000 Message-id: <20010708134638.30843.qmail@sourceware.cygnus.com> X-SW-Source: 2001-07/msg00198.html List-Id: >Number: 3608 >Category: c++ >Synopsis: Virtual funtions called with wrong this pointer when having virtual inheritance >Confidential: no >Severity: serious >Priority: medium >Responsible: unassigned >State: open >Class: sw-bug >Submitter-Id: net >Arrival-Date: Sun Jul 08 06:56:00 PDT 2001 >Closed-Date: >Last-Modified: >Originator: Vladimir Panov >Release: 2.95.3 20010315 (release) >Organization: >Environment: i386-slackware-linux >Description: When invoking a virtual function via a base class pointer the function receives a wrong this pointer. This happens only when having virtual inheritance. I suppose it receives the this pointer for the most-derived object. This causes no problem (i.e. both this pointers in the ctor and the virtual method are equal), because object b is the most-derived one: #include #include using namespace std; class A { public: A (void) { } virtual ~A (void) { } virtual void t (void) { } }; void T (A *a) { a->t (); } class B : public virtual A { public: B (void) { cerr << "Ctor: " << hex << (unsigned)this << endl; T (this); } virtual ~B (void) { } virtual void t (void) { cerr << "t: " << hex << (unsigned)this << endl; } }; int main (void) { B b; return 0; } This causes no problem, because class C does not have extra members over class B and (C *) is equivalent to (B *): #include #include using namespace std; class A { public: A (void) { } virtual ~A (void) { } virtual void t (void) { } }; void T (A *a) { a->t (); } class B : public virtual A { public: B (void) { cerr << "Ctor: " << hex << (unsigned)this << endl; T (this); } virtual ~B (void) { } virtual void t (void) { cerr << "t: " << hex << (unsigned)this << endl; } }; class C : public B { public: C (void) { } virtual ~C (void) { } }; int main (void) { C c; return 0; } This causes the problem, because (I suppose) the virtual inheritance of class C adds some hidden extra fields: #include #include using namespace std; class A { public: A (void) { } virtual ~A (void) { } virtual void t (void) { } }; void T (A *a) { a->t (); } class B : public virtual A { public: B (void) { cerr << "Ctor: " << hex << (unsigned)this << endl; T (this); } virtual ~B (void) { } virtual void t (void) { cerr << "t: " << hex << (unsigned)this << endl; } }; class C : public virtual B { public: C (void) { } virtual ~C (void) { } }; int main (void) { C c; return 0; } This causes the problem, because class C has extra fields over class B: #include #include using namespace std; class A { public: A (void) { } virtual ~A (void) { } virtual void t (void) { } }; void T (A *a) { a->t (); } class B : public virtual A { public: B (void) { cerr << "Ctor: " << hex << (unsigned)this << endl; T (this); } virtual ~B (void) { } virtual void t (void) { cerr << "t: " << hex << (unsigned)this << endl; } }; class C : public B { int i; public: C (void) { } virtual ~C (void) { } }; int main (void) { C c; return 0; } Both the erroneous examples are OK with Micro$oft Visual C++ 6.0. Shame on you! :-))) In the following days I will try to test these examples on Solaris 7 ULTRASPARC with gcc 2.9x.xx to find out if this is an architecture-specific or general bug. >How-To-Repeat: g++ example.cpp and run the resulting a.out. >Fix: None. >Release-Note: >Audit-Trail: >Unformatted: