Title
Requirements for operands of delete-expressions and deallocation functions
Status
c++11
Section
7.6.2.9 [expr.delete]
Submitter
Daniel Krügler

Created on 2010-03-01.00:00:00 last changed 130 months ago

Messages

Date: 2010-11-15.00:00:00

[Voted into the WP at the November, 2010 meeting.]

Date: 2010-10-15.00:00:00

Proposed resolution (October, 2010):

  1. Change 7.6.2.9 [expr.delete] paragraph 2 as follows:

  2. 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 section. In either alternative, the value of the operand of delete may be a null pointer value. If it is not a null pointer value, in In the first alternative (delete object), the value of the operand of delete shall may be a null pointer value, a pointer to a non-array object created by a previous new-expression, or a pointer to a subobject (6.7.2 [intro.object]) representing a base class of such an object ( 11.7 [class.derived]). If not, the behavior is undefined. In the second alternative (delete array), the value of the operand of delete shall may be the a null pointer value or a pointer value which that resulted from a previous array new-expression.79 If not, the behavior is undefined. [Note: this means that the syntax of the delete-expression must match the type of the object allocated by new new, not the syntax of the new-expression. —end note]...
  3. Change 6.7.5.5.3 [basic.stc.dynamic.deallocation] paragraph 3 as follows:

  4. ...Otherwise, the behavior is undefined if the value supplied to operator delete(void*) in the standard library shall be is not one of the values returned by a previous invocation of either operator new(std::size_t) or operator new(std::size_t, const std::nothrow_t&) in the standard library, and the behavior is undefined if the value supplied to operator delete[](void*) in the standard library shall be is not one of the values returned by a previous invocation of either operator new[](std::size_t) or operator new[](std::size_t, const std::nothrow_t&) in the standard library.
Date: 2022-02-18.07:47:23

According to 7.6.2.9 [expr.delete] paragraph 2,

...in the first alternative (delete object), the value of the operand of delete shall be a pointer to a non-array object or a pointer to a subobject (6.7.2 [intro.object]) representing a base class of such an object (11.7 [class.derived]). If not, the behavior is undefined. In the second alternative (delete array), the value of the operand of delete shall be the pointer value which resulted from a previous array new-expression.79 If not, the behavior is undefined.

The second part of this specification makes it clear that an array object being deleted must have been allocated via new. However, the first part, for the non-array object, completely omits this vital requirement, requiring only that it not be an array.

The corresponding requirement for an argument to a deallocation function is found in 6.7.5.5.3 [basic.stc.dynamic.deallocation] paragraph 3:

...the value supplied to operator delete(void*) in the standard library shall be one of the values returned by a previous invocation of either operator new(std::size_t) or operator new(std::size_t, const std::nothrow_t&) in the standard library, and the value supplied to operator delete[](void*) in the standard library shall be one of the values returned by a previous invocation of either operator new[](std::size_t) or operator new[](std::size_t, const std::nothrow_t&) in the standard library.

This correctly states the required provenance of the pointer, but it does so using “shall,” which is inappropriate for a runtime requirement. This wording should be recast in terms of undefined behavior if the requirement is not met.

History
Date User Action Args
2014-03-03 00:00:00adminsetstatus: fdis -> c++11
2011-04-10 00:00:00adminsetstatus: dr -> fdis
2010-11-29 00:00:00adminsetmessages: + msg3159
2010-11-29 00:00:00adminsetstatus: tentatively ready -> dr
2010-10-18 00:00:00adminsetmessages: + msg2979
2010-10-18 00:00:00adminsetstatus: drafting -> tentatively ready
2010-08-23 00:00:00adminsetstatus: open -> drafting
2010-03-01 00:00:00admincreate