[gnu.g++.bug] BUG in multiple inheritance

jj@idris.id.dk (Jesper Joergensen [ris]) (02/14/90)

ENVIRONMENT
===========

    Compiler:	G++	version 1.36.4	(configured for 'vax')
    Back-end:	GCC	version 1.36.93	(configured for 'vax')
    System:	Ultrix	version 2.2-1 Worksystem v1.1 System #2
    Machine:	DEC VAXstation 2000


SUMMARY
=======

    Given the following classes:
	Base1:		with a virtual destructor
	Base2:		with a normal destructor
	Derived1:	derived public from Base1 and private from Base2,
			without an explicitly defined destructor
	Derived2:	derived public from Base1 and private from Base2,
			with an empty (dummy) destructor

    When an object of class Derived1 is delete'ed through a pointer to Base1
    the virtual destruction FAILS to invoke the destructor for Base2.
     However, when an object of class Derived2 is delete'ed through a pointer
    to Base1 the virtual destruction WILL invoke the destructor for Base2.


EXAMPLE PROGRAM
===============

****** START ******
#include <stream.h>

class Base1 {				// Base with virtual destructor
  int member1 ;
public:
  virtual ~Base1() { cout << "~Base1() executed\n" ; }
  Base1(int x) { cout << "Base1(int x) executed\n" ; member1 = x ; }
} ;

class Base2 {				// Base with normal destructor
  int member2 ;
public:
  ~Base2() { cout << "~Base2() executed\n" ; }
  Base2(int x) { cout << "Base2(int x) executed\n" ; member2 = x ; }
} ;

class Derived1 : public Base1, Base2 {	// Derived without explicit destructor
public:
  Derived1(int x) : Base1(x), Base2(x) {
    cout << "Derived1(int x) executed\n" ;
  }
} ;

class Derived2 : public Base1, Base2 {	// Derived with empty destructor
public:
  ~Derived2() { }
  Derived2(int x) : Base1(x), Base2(x) {
    cout << "Derived2(int x) executed\n" ;
  }
} ;

int main(const int argc, const char *argv) {
  Base1 *_bptr ;
  _bptr = new Derived1(12) ;		// Why isn't ~Base2() called here ....
  delete _bptr ;
  _bptr = new Derived2(12) ;		// When it is called here ????
  delete _bptr ;
  return 0 ;
}
******* END *******


EXAMPLE OUTPUT
==============

****** START ******
Base1(int x) executed
Base2(int x) executed
Derived1(int x) executed
~Base1() executed
Base1(int x) executed
Base2(int x) executed
Derived2(int x) executed
~Base2() executed
~Base1() executed
******* END *******


Am I missing something ?? I can't find anything demanding the call of ~Base2()
in the first case, but it seems obvious that it should. The destruction of ALL
base classes in other situation have always been independent of whether the
derived class has a destructor itself.


Please inform me if I'm wrong, so that I know my way in the future.

	Jesper Jorgensen	jj@idris.id.dk

	Research associate
	Department of Computer Science
	Technical University of Denmark
	DK-2800 Lyngby
	DENMARK