[expr.delete] (original) (raw)
7 Expressions [expr]
7.6 Compound expressions [expr.compound]
7.6.2 Unary expressions [expr.unary]
7.6.2.9 Delete [expr.delete]
The first alternative is asingle-object delete expression, and the second is an array delete expression.
Whenever the delete keyword is immediately followed by empty square brackets, it shall be interpreted as the second alternative.76
The operand shall be of pointer to object type or of class type.
The delete-expression's result has typevoid.
If the operand has a class type, the operand is converted to a pointer type by calling the above-mentioned conversion function, and the converted operand is used in place of the original operand for the remainder of this subclause.
In a single-object delete expression, the value of the operand ofdelete may be a null pointer value, a pointer to a non-array object created by a previous new-expression, or a pointer to asubobject representing abase class of such an object.
If not, the behavior is undefined.
In an array delete expression, the value of the operand of deletemay be a null pointer value or a pointer value that resulted from a previous array new-expression.78
If not, the behavior is undefined.
[Note 1:
This means that the syntax of the delete-expression must match the type of the object allocated by new, not the syntax of thenew-expression.
— _end note_]
[Note 2:
A pointer to a const type can be the operand of adelete-expression; it is not necessary tocast away the constnessof the pointer expression before it is used as the operand of the delete-expression.
— _end note_]
In a single-object delete expression, if the static type of the object to be deleted is different from its dynamic type and the selected deallocation function (see below) is not a destroying operator delete, the static type shall be a base class of the dynamic type of the object to be deleted and the static type shall have a virtual destructor or the behavior is undefined.
In an array delete expression, if the dynamic type of the object to be deleted differs from its static type, the behavior is undefined.
If the object being deleted has incomplete class type at the point of deletion and the complete class has a non-trivial destructor or a deallocation function, the behavior is undefined.
If the value of the operand of the delete-expression is not a null pointer value and the selected deallocation function (see below) is not a destroying operator delete, the delete-expression will invoke the destructor (if any) for the object or the elements of the array being deleted.
In the case of an array, the elements will be destroyed in order of decreasing address (that is, in reverse order of the completion of their constructor; see [class.base.init]).
If the value of the operand of the delete-expression is not a null pointer value, then:
- The value returned from the allocation call of the new-expression shall be passed as the first argument to the deallocation function.
- Otherwise, if the allocation was extended or was provided by extending the allocation of another new-expression, and thedelete-expression for every other pointer value produced by anew-expression that had storage provided by the extendednew-expression has been evaluated, thedelete-expression shall call a deallocation function.
The value returned from the allocation call of the extended new-expressionshall be passed as the first argument to the deallocation function. - Otherwise, the delete-expression will not call a deallocation function.
[Note 3:
The deallocation function is called regardless of whether the destructor for the object or some element of the array throws an exception.
— _end note_]
If the value of the operand of the delete-expression is a null pointer value, it is unspecified whether a deallocation function will be called as described above.
When the keyword delete in a delete-expression is preceded by the unary :: operator, the deallocation function's name is looked up in global scope.
Otherwise, the lookup considers class-specific deallocation functions ([class.free]).
If no class-specific deallocation function is found, the deallocation function's name is looked up in global scope.
If deallocation function lookup finds more than one usual deallocation function, the function to be called is selected as follows:
- If any of the deallocation functions is a destroying operator delete, all deallocation functions that are not destroying operator deletes are eliminated from further consideration.
- If the type has new-extended alignment, a function with a parameter of type std::align_val_t is preferred; otherwise a function without such a parameter is preferred.
If any preferred functions are found, all non-preferred functions are eliminated from further consideration. - If exactly one function remains, that function is selected and the selection process terminates.
- If the deallocation functions have class scope, the one without a parameter of type std::size_t is selected.
- If the type is complete and if, for an array delete expression only, the operand is a pointer to a class type with a non-trivial destructor or a (possibly multi-dimensional) array thereof, the function with a parameter of type std::size_t is selected.
- Otherwise, it is unspecified whether a deallocation function with a parameter of type std::size_tis selected.
For a single-object delete expression, the deleted object is the object denoted by the operand if its static type does not have a virtual destructor, and its most-derived object otherwise.
[Note 5:
If the deallocation function is not a destroying operator delete and the deleted object is not the most derived object in the former case, the behavior is undefined, as stated above.
— _end note_]
For an array delete expression, the deleted object is the array object.
When a delete-expressionis executed, the selected deallocation function shall be called with the address of the deleted object in a single-object delete expression, or the address of the deleted object suitably adjusted for the array allocation overhead ([expr.new]) in an array delete expression, as its first argument.
[Note 6:
Any cv-qualifiers in the type of the deleted object are ignored when forming this argument.
— _end note_]
If a destroying operator delete is used, an unspecified value is passed as the argument corresponding to the parameter of type std::destroying_delete_t.
If a deallocation function with a parameter of type std::align_val_tis used, the alignment of the type of the deleted object is passed as the corresponding argument.
If a deallocation function with a parameter of type std::size_t is used, the size of the deleted object in a single-object delete expression, or of the array plus allocation overhead in an array delete expression, is passed as the corresponding argument.
[Note 7:
If this results in a call to a replaceable deallocation function, and either the first argument was not the result of a prior call to a replaceable allocation function or the second or third argument was not the corresponding argument in said call, the behavior is undefined ([new.delete.single], [new.delete.array]).
— _end note_]