This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

::delete() reference generated but not used


We have a bunch of code that follows this general pattern:

#include <stdio.h>
#include <malloc.h>

//void operator delete(void * where)
//{
//	printf("%s called\n", __PRETTY_FUNCTION__);
//}

////////////////////////////////////////////////////////////////////////////////
class A
////////////////////////////////////////////////////////////////////////////////
{
public:
	A(void);
	~A(void);

    void * operator new(size_t size) throw();
    void operator delete(void * where);

	int a;
};

A::A(void)
{
}

A::~A(void)
{
}

void * A::operator new(size_t size) throw()
{
	return malloc(size);
}

void A::operator delete(void * where)
{
	printf("%s called\n", __PRETTY_FUNCTION__);
	free(where);
}

////////////////////////////////////////////////////////////////////////////////
class B
////////////////////////////////////////////////////////////////////////////////
{
public:
	virtual ~B(void) {}

	virtual void hello(void) = 0;

	int b;
};

////////////////////////////////////////////////////////////////////////////////
class foo : public A, public B
////////////////////////////////////////////////////////////////////////////////
{
public:
	foo(void);
	virtual ~foo(void);

	virtual void hello(void);
};

foo::foo(void)
{
}

foo::~foo(void)
{
}

void foo::hello(void)
{
	printf("%s called\n", __PRETTY_FUNCTION__);
}

////////////////////////////////////////////////////////////////////////////////
int main(int argc, char * argv[])
////////////////////////////////////////////////////////////////////////////////
{
	foo * f = new foo();

	f->hello();

	delete f;

	return 0;
}

In other words, a class derived from two base classes.  One is a
storage management base class A that defines delete().  The other (B)
happens to have a virtual method, so to silence warnings we also give
it a virtual destructor.

There are no objects of that second class (B) -- only objects of class
foo which is derived from A and B.  

So we expect A::delete() to be called for the destruction of objects
of class foo, and indeed it is.

However, even though B is only a base class, it seems that gcc is
still generating in-charge destructors for B.  As a result, we end up
with references in the object file to ::delete() which means we get
link errors because that operator isn't defined anywhere.

As a workaround we can define ::delete(){panic();} but that's not the
desirable answer.  It would be better if gcc could avoid generating
that unused code.

      paul


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]