[comp.lang.c++] Destructor not called when operator= is inline

horstman@mathcs.sjsu.edu (Cay Horstmann) (04/20/91)

Here is a truly annoying bug with BC++ 2.0 which took me days to nail
down. When defining an operator= inline, there was a memory leak which
disappeared when making it into a regular function call. The circumstances
look weird from the distillation below but they aren't so uncommon
in practice. 

I sent a copy to bugs@borland.com. 

If you have a memory leak with BC++, watch those destructors and stay
away from inline functions defined in the class definition. (Defining
them inline OUTSIDE the class definition is ok!!!)

Cay



/****************************************************************************

This file illustrates a bug with Borland C++ Version 2.0. Here are the
ingredients:
	- A class X with constructors, copy constructor, destructor, operator=
	- A class Y having a member of class X
	- An operator= in class Y calling the operator= in class X
Here is the symptom:
	- If Y::operator= is inline in the class declaration, the program fails
     to call a destructor. (Compile with the OK flag undefined.)
	- If Y::operator= is not in the class declaration, the program works 
     correctly (compile with -DOK), even when declared inline !!!
I have not tried to pare this down any further. This is the condensation
from a largish piece of real code which had a memory leak. It is possible
that not all the ingredients present here are necessary for causing the
error. 

****************************************************************************/

#include <stdio.h>

class X
{	int x;
public:
	X() { x = 0; printf( "Created X at %p\n", this ); }
	X(int n) { x = n; printf( "Created X at %p\n", this ); }
	X(const X& b) { x = b.x; printf( "Created X at %p\n", this ); }
	X& operator=( const X& b ) { x = b.x; return *this; }
	~X() { printf( "Deleted X at %p\n", this ); }
};

class Y 
{	X x;
public:
	Y() : x(0) {}
	Y( int n ) : x(n) {}
#ifdef OK
	Y& operator=( const Y& b );
#else
	Y& operator=( const Y& b ) { x = b.x; return *this; }
#endif

};

#ifdef OK
// inline also works
Y& Y::operator=( const Y& b ) { x = b.x; return *this; }
#endif

main()
{	Y y;
	y = 4;
}