Reputation: 25311
From the C++ standard (ISO/IEC 14882:2003(E)), §12.5.4, about overloading operator delete
:
If a delete-expression begins with a unary :: operator, the deallocation function's name is looked up in global scope. Otherwise, if the delete-expression is used to deallocate a class object whose static type has a virtual destructor, the deallocation function is the one found by the lookup in the definition of the dynamic type's virtual destructor (12.4). Otherwise, if the delete-expression is used to deallocate an object of class T or array thereof, the static and dynamic types of the object shall be identical and the deallocation function's name is looked up in the scope of T. If this lookup fails to find the name, the name is looked up in the global scope. If the result of the lookup is ambiguous or inaccessible, or if the lookup selects a placement deallocation function, the program is ill-formed.
§12.5.7 is also interesting:
Since member allocation and deallocation functions are static they cannot be virtual. [Note: however, when the cast-expression of a delete-expression refers to an object of class type, because the deallocation function actually called is looked up in the scope of the class that is the dynamic type of the object, if the destructor is virtual, the effect is the same. For example,
struct B {
virtual ˜B();
void operator delete(void*, size_t);
};
struct D : B {
void operator delete(void*);
};
void f()
{
B* bp = new D;
delete bp; // uses D::operator delete(void*)
}
Here, storage for the non-array object of class D is deallocated by D::operator delete(), due to the virtual destructor.]
After reading this, I am wondering...
§5.3.5.5 may also be relevant:
In the first alternative (delete object), if the static type of the operand is different from its dynamic type, the static type shall be a base class of the operand's dynamic type and the static type shall have a virtual destructor or the behavior is undefined. In the second alternative (delete array) if the dynamic type of the object to be deleted differs from its static type, the behavior is undefined.
Upvotes: 7
Views: 2976
Reputation: 3490
After dig into the assembly code in emit by GCC 4.8
The GCC will generate two piece of code (for class whose destructor is virtual):
One is assembly snippet#1 for {Destructor + Dealloc}
The other is assembly snippet#2 for {Destructor only}
And for the class whose destructor is not virtual, the call deallocation function instruction will generate in the point where you call delete.
(Following discussion assume the destructor is virtual) So for following code:
delete C // This will be translate as call snippet#1 for the correct dynamic type
And if you code is following:
p->C::~C() // this will be translate to call snippet#2
So the deallocate function is bind together with the virtual destructor. So I think this will answere your question about how the deallocate function are implement like virtual but also static.
Upvotes: 0
Reputation: 299770
I don't know much about VC++ ABI, but the Itanium ABI is well documented.
Looking up at the name mangling scheme, one see:
<ctor-dtor-name> ::= C1 # complete object constructor
::= C2 # base object constructor
::= C3 # complete object allocating constructor
::= D0 # deleting destructor
::= D1 # complete object destructor
::= D2 # base object destructor
Of interest: D0 # deleting destructor
, which means that even though delete
is non virtual, since it is called from the virtual destructor, it can be considered virtual for all effects and purposes.
Upvotes: 7