stuart@NECAM.tdd.sj.nec.com (Stuart Palmer) (01/08/91)
If you call a virtual member function from a destructor, what is the behavior? We ran some tests and found differences between Glockenspiel 1.2 and Sun 2.0 compilers. In Sun 2.0, if you call a virtual member function from a destructor, the "actual" virtual function that is compiled into the class vtbl will not get called. Rather, the virtual function at the class level where the call was made gets called. If this is confusing, see the code sample below. This is different than Glockenspiel 1.2. 1.2 calls the virtual function from the vtbl (as might be expected?). Is this a bug in one of the compilers? I looked throught the Turbo C++ bug list and found a similar bug concerning virtual functions called from member functions. I would appreciate someone describing the Correct (tm) behavior to me. Thanks! **********************************Code example******************************** class Base { public: Base(); virtual ~Base(); virtual void some_func(); } Base::Base(){} Base::~Base(){ some_func(); } void Base::some_func(){ printf ("Base called.\n"); } class Derived : public Base { public: Derived(); ~Derived(); void some_func(); } Derived::Derived(){} Derived::~Derived(){ } void Derived::some_func(){ printf ("Derived called.\n"); } main() { Derived d; } **********************************Output************************************** 1.2 output: Derived called. 2.0 output: Base called. ****************************************************************************** -- Stuart Palmer stuart@tdd.sj.nec.com NEC America, Inc. 110 Rio Robles San Jose, CA 95134
jak@cs.brown.edu (Jak Kirman) (01/09/91)
In article <424@nec-gw.nec.com> stuart@NECAM.tdd.sj.nec.com (Stuart Palmer) writes:
- If you call a virtual member function from a destructor, what is
- the behavior? We ran some tests and found differences between
- Glockenspiel 1.2 and Sun 2.0 compilers.
-
- In Sun 2.0, if you call a virtual member function from
- a destructor, the "actual" virtual function that is compiled into
- the class vtbl will not get called. Rather, the virtual function
- at the class level where the call was made gets called. If this is
- confusing, see the code sample below.
-
- This is different than Glockenspiel 1.2. 1.2 calls the virtual
- function from the vtbl (as might be expected?).
-
- Is this a bug in one of the compilers? I looked throught the Turbo
- C++ bug list and found a similar bug concerning virtual functions
- called from member functions. I would appreciate someone
- describing the Correct (tm) behavior to me.
-
- Thanks!
-
- **********************************Code example********************************
-
- class Base {
- public:
- > Base();
- > virtual ~Base();
- > virtual void some_func();
- }
- Base::Base(){}
- Base::~Base(){ some_func(); }
- void Base::some_func(){ printf ("Base called.\n"); }
-
- class Derived : public Base {
- public:
- > Derived();
- > ~Derived();
- > void some_func();
- }
- Derived::Derived(){}
- Derived::~Derived(){ }
- void Derived::some_func(){ printf ("Derived called.\n"); }
-
- main() {
- > Derived d;
- }
From Ellis & Stroustrup ARM 12.7 Constructors and destructors
Member functions may be called in constructors and destructors.
This implies that virtual functions may be called (directly or
indirectly). The function called will be the one defined in the
constructor's (or destructor's) own class or its bases, but not any
function overriding it in a derived class. This ensures that
unconstructed objects will not be accessed during construction or
destruction.
The problem is that the some_func defined in Derived may access data
belonging to the Derived object which is destroyed by the Derived
destructor. Since the Derived destructor is called before the Base
destructor, it would be unsafe to call functions which might operate on
that data. The behaviour of Sun's compiler is correct.
Jak jak@cs.brown.edu
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Tell me what company thou keepest, and I'll tell thee what thou art.
-- Cervantes
sarima@tdatirv.UUCP (Stanley Friesen) (01/15/91)
In article <424@nec-gw.nec.com> stuart@NECAM.tdd.sj.nec.com (Stuart Palmer) writes: > >If you call a virtual member function from a destructor, what is >the behavior? >In Sun 2.0, if you call a virtual member function from >a destructor, the "actual" virtual function that is compiled into >the class vtbl will not get called. Rather, the virtual function >at the class level where the call was made gets called. This is correct, at least for version 2.XC++. This is so because by the time a destructor is called all derived classes have been destroyed, so the object is no longer a derived class object. Thus the destuctor can make a 'static' call to the function. >This is different than Glockenspiel 1.2. 1.2 calls the virtual >function from the vtbl (as might be expected?). This is (or would be) wrong for a 2.X compiler, but it may be that as a 1.2 compiler this was correct at the time. (I.e. this could be something that changed between version 1.2 and 2.0 of cfront). >Is this a bug in one of the compilers? It is either a bug or an archaism in the Glockenspiel compiler. By the way, this should probably be in the FAQ, it has been asked enough. -- --------------- uunet!tdatirv!sarima (Stanley Friesen)