From Jason Turner

[expr.delete]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpqzw8xwel/{from.md → to.md} +89 -68
tmp/tmpqzw8xwel/{from.md → to.md} RENAMED
@@ -1,51 +1,51 @@
1
- ### Delete <a id="expr.delete">[[expr.delete]]</a>
2
 
3
- The *delete-expression* operator destroys a most derived object (
4
- [[intro.object]]) or array created by a *new-expression*.
5
 
6
  ``` bnf
7
  delete-expression:
8
- '::'ₒₚₜ 'delete' cast-expression
9
- '::'ₒₚₜ 'delete [ ]' cast-expression
10
  ```
11
 
12
- The first alternative is for non-array objects, and the second is for
13
- arrays. Whenever the `delete` keyword is immediately followed by empty
14
- square brackets, it shall be interpreted as the second alternative.[^20]
15
- The operand shall be of pointer to object type or of class type. If of
16
- class type, the operand is contextually implicitly converted (Clause 
17
- [[conv]]) to a pointer to object type.[^21] The *delete-expression*’s
18
- result has type `void`.
19
 
20
  If the operand has a class type, the operand is converted to a pointer
21
  type by calling the above-mentioned conversion function, and the
22
  converted operand is used in place of the original operand for the
23
- remainder of this section. In the first alternative (*delete object*),
24
- the value of the operand of `delete` may be a null pointer value, a
25
- pointer to a non-array object created by a previous *new-expression*, or
26
- a pointer to a subobject ([[intro.object]]) representing a base class
27
- of such an object (Clause  [[class.derived]]). If not, the behavior is
28
- undefined. In the second alternative (*delete array*), the value of the
29
- operand of `delete` may be a null pointer value or a pointer value that
30
- resulted from a previous array *new-expression*.[^22] If not, the
31
- behavior is undefined.
32
 
33
  [*Note 1*: This means that the syntax of the *delete-expression* must
34
  match the type of the object allocated by `new`, not the syntax of the
35
  *new-expression*. — *end note*]
36
 
37
  [*Note 2*: A pointer to a `const` type can be the operand of a
38
- *delete-expression*; it is not necessary to cast away the constness (
39
- [[expr.const.cast]]) of the pointer expression before it is used as the
40
  operand of the *delete-expression*. — *end note*]
41
 
42
- In the first alternative (*delete object*), if the static type of the
43
- object to be deleted is different from its dynamic type, the static type
44
- shall be a base class of the dynamic type of the object to be deleted
45
- and the static type shall have a virtual destructor or the behavior is
46
- undefined. In the second alternative (*delete array*) if the dynamic
 
47
  type of the object to be deleted differs from its static type, the
48
  behavior is undefined.
49
 
50
  The *cast-expression* in a *delete-expression* shall be evaluated
51
  exactly once.
@@ -53,25 +53,26 @@ exactly once.
53
  If the object being deleted has incomplete class type at the point of
54
  deletion and the complete class has a non-trivial destructor or a
55
  deallocation function, the behavior is undefined.
56
 
57
  If the value of the operand of the *delete-expression* is not a null
58
- pointer value, the *delete-expression* will invoke the destructor (if
59
- any) for the object or the elements of the array being deleted. In the
60
- case of an array, the elements will be destroyed in order of decreasing
61
- address (that is, in reverse order of the completion of their
62
- constructor; see  [[class.base.init]]).
 
63
 
64
  If the value of the operand of the *delete-expression* is not a null
65
  pointer value, then:
66
 
67
  - If the allocation call for the *new-expression* for the object to be
68
- deleted was not omitted and the allocation was not extended (
69
- [[expr.new]]), the *delete-expression* shall call a deallocation
70
- function ([[basic.stc.dynamic.deallocation]]). The value returned
71
- from the allocation call of the *new-expression* shall be passed as
72
- the first argument to the deallocation function.
73
  - Otherwise, if the allocation was extended or was provided by extending
74
  the allocation of another *new-expression*, and the
75
  *delete-expression* for every other pointer value produced by a
76
  *new-expression* that had storage provided by the extended
77
  *new-expression* has been evaluated, the *delete-expression* shall
@@ -88,57 +89,77 @@ exception. — *end note*]
88
  If the value of the operand of the *delete-expression* is a null pointer
89
  value, it is unspecified whether a deallocation function will be called
90
  as described above.
91
 
92
  [*Note 4*: An implementation provides default definitions of the global
93
- deallocation functions `operator delete` for non-arrays (
94
- [[new.delete.single]]) and `operator delete[]` for arrays (
95
- [[new.delete.array]]). A C++ program can provide alternative definitions
96
- of these functions ([[replacement.functions]]), and/or class-specific
97
- versions ([[class.free]]). — *end note*]
98
 
99
  When the keyword `delete` in a *delete-expression* is preceded by the
100
  unary `::` operator, the deallocation function’s name is looked up in
101
  global scope. Otherwise, the lookup considers class-specific
102
- deallocation functions ([[class.free]]). If no class-specific
103
- deallocation function is found, the deallocation function’s name is
104
- looked up in global scope.
105
 
106
  If deallocation function lookup finds more than one usual deallocation
107
  function, the function to be called is selected as follows:
108
 
 
 
 
109
  - If the type has new-extended alignment, a function with a parameter of
110
  type `std::align_val_t` is preferred; otherwise a function without
111
- such a parameter is preferred. If exactly one preferred function is
112
- found, that function is selected and the selection process terminates.
113
- If more than one preferred function is found, all non-preferred
114
- functions are eliminated from further consideration.
115
  - If the deallocation functions have class scope, the one without a
116
  parameter of type `std::size_t` is selected.
117
- - If the type is complete and if, for the second alternative (delete
118
- array) only, the operand is a pointer to a class type with a
119
- non-trivial destructor or a (possibly multi-dimensional) array
120
- thereof, the function with a parameter of type `std::size_t` is
121
- selected.
122
  - Otherwise, it is unspecified whether a deallocation function with a
123
  parameter of type `std::size_t` is selected.
124
 
 
 
 
 
 
 
 
 
 
125
  When a *delete-expression* is executed, the selected deallocation
126
- function shall be called with the address of the most-derived object in
127
- the *delete object* case, or the address of the object suitably adjusted
128
- for the array allocation overhead ([[expr.new]]) in the *delete array*
129
- case, as its first argument. If a deallocation function with a parameter
 
 
 
 
 
 
 
130
  of type `std::align_val_t` is used, the alignment of the type of the
131
- object to be deleted is passed as the corresponding argument. If a
132
  deallocation function with a parameter of type `std::size_t` is used,
133
- the size of the most-derived type, or of the array plus allocation
134
- overhead, respectively, is passed as the corresponding argument. [^23]
 
135
 
136
- [*Note 5*: If this results in a call to a usual deallocation function,
137
- and either the first argument was not the result of a prior call to a
138
- usual allocation function or the second argument was not the
139
- corresponding argument in said call, the behavior is undefined (
140
- [[new.delete.single]], [[new.delete.array]]). — *end note*]
 
141
 
142
  Access and ambiguity control are done for both the deallocation function
143
- and the destructor ([[class.dtor]],  [[class.free]]).
144
 
 
1
+ #### Delete <a id="expr.delete">[[expr.delete]]</a>
2
 
3
+ The *delete-expression* operator destroys a most derived object
4
+ [[intro.object]] or array created by a *new-expression*.
5
 
6
  ``` bnf
7
  delete-expression:
8
+ '::'ₒₚₜ delete cast-expression
9
+ '::'ₒₚₜ delete '[' ']' cast-expression
10
  ```
11
 
12
+ The first alternative is a *single-object delete expression*, and the
13
+ second is an *array delete expression*. Whenever the `delete` keyword is
14
+ immediately followed by empty square brackets, it shall be interpreted
15
+ as the second alternative.[^25] The operand shall be of pointer to
16
+ object type or of class type. If of class type, the operand is
17
+ contextually implicitly converted [[conv]] to a pointer to object
18
+ type.[^26] The *delete-expression*’s result has type `void`.
19
 
20
  If the operand has a class type, the operand is converted to a pointer
21
  type by calling the above-mentioned conversion function, and the
22
  converted operand is used in place of the original operand for the
23
+ remainder of this subclause. In a single-object delete expression, the
24
+ value of the operand of `delete` may be a null pointer value, a pointer
25
+ to a non-array object created by a previous *new-expression*, or a
26
+ pointer to a subobject [[intro.object]] representing a base class of
27
+ such an object [[class.derived]]. If not, the behavior is undefined. In
28
+ an array delete expression, the value of the operand of `delete` may be
29
+ a null pointer value or a pointer value that resulted from a previous
30
+ array *new-expression*.[^27] If not, the behavior is undefined.
 
31
 
32
  [*Note 1*: This means that the syntax of the *delete-expression* must
33
  match the type of the object allocated by `new`, not the syntax of the
34
  *new-expression*. — *end note*]
35
 
36
  [*Note 2*: A pointer to a `const` type can be the operand of a
37
+ *delete-expression*; it is not necessary to cast away the constness
38
+ [[expr.const.cast]] of the pointer expression before it is used as the
39
  operand of the *delete-expression*. — *end note*]
40
 
41
+ In a single-object delete expression, if the static type of the object
42
+ to be deleted is different from its dynamic type and the selected
43
+ deallocation function (see below) is not a destroying operator delete,
44
+ the static type shall be a base class of the dynamic type of the object
45
+ to be deleted and the static type shall have a virtual destructor or the
46
+ behavior is undefined. In an array delete expression, if the dynamic
47
  type of the object to be deleted differs from its static type, the
48
  behavior is undefined.
49
 
50
  The *cast-expression* in a *delete-expression* shall be evaluated
51
  exactly once.
 
53
  If the object being deleted has incomplete class type at the point of
54
  deletion and the complete class has a non-trivial destructor or a
55
  deallocation function, the behavior is undefined.
56
 
57
  If the value of the operand of the *delete-expression* is not a null
58
+ pointer value and the selected deallocation function (see below) is not
59
+ a destroying operator delete, the *delete-expression* will invoke the
60
+ destructor (if any) for the object or the elements of the array being
61
+ deleted. In the case of an array, the elements will be destroyed in
62
+ order of decreasing address (that is, in reverse order of the completion
63
+ of their constructor; see  [[class.base.init]]).
64
 
65
  If the value of the operand of the *delete-expression* is not a null
66
  pointer value, then:
67
 
68
  - If the allocation call for the *new-expression* for the object to be
69
+ deleted was not omitted and the allocation was not extended
70
+ [[expr.new]], the *delete-expression* shall call a deallocation
71
+ function [[basic.stc.dynamic.deallocation]]. The value returned from
72
+ the allocation call of the *new-expression* shall be passed as the
73
+ first argument to the deallocation function.
74
  - Otherwise, if the allocation was extended or was provided by extending
75
  the allocation of another *new-expression*, and the
76
  *delete-expression* for every other pointer value produced by a
77
  *new-expression* that had storage provided by the extended
78
  *new-expression* has been evaluated, the *delete-expression* shall
 
89
  If the value of the operand of the *delete-expression* is a null pointer
90
  value, it is unspecified whether a deallocation function will be called
91
  as described above.
92
 
93
  [*Note 4*: An implementation provides default definitions of the global
94
+ deallocation functions `operator delete` for non-arrays
95
+ [[new.delete.single]] and `operator delete[]` for arrays
96
+ [[new.delete.array]]. A C++ program can provide alternative definitions
97
+ of these functions [[replacement.functions]], and/or class-specific
98
+ versions [[class.free]]. — *end note*]
99
 
100
  When the keyword `delete` in a *delete-expression* is preceded by the
101
  unary `::` operator, the deallocation function’s name is looked up in
102
  global scope. Otherwise, the lookup considers class-specific
103
+ deallocation functions [[class.free]]. If no class-specific deallocation
104
+ function is found, the deallocation function’s name is looked up in
105
+ global scope.
106
 
107
  If deallocation function lookup finds more than one usual deallocation
108
  function, the function to be called is selected as follows:
109
 
110
+ - If any of the deallocation functions is a destroying operator delete,
111
+ all deallocation functions that are not destroying operator deletes
112
+ are eliminated from further consideration.
113
  - If the type has new-extended alignment, a function with a parameter of
114
  type `std::align_val_t` is preferred; otherwise a function without
115
+ such a parameter is preferred. If any preferred functions are found,
116
+ all non-preferred functions are eliminated from further consideration.
117
+ - If exactly one function remains, that function is selected and the
118
+ selection process terminates.
119
  - If the deallocation functions have class scope, the one without a
120
  parameter of type `std::size_t` is selected.
121
+ - If the type is complete and if, for an array delete expression only,
122
+ the operand is a pointer to a class type with a non-trivial destructor
123
+ or a (possibly multi-dimensional) array thereof, the function with a
124
+ parameter of type `std::size_t` is selected.
 
125
  - Otherwise, it is unspecified whether a deallocation function with a
126
  parameter of type `std::size_t` is selected.
127
 
128
+ For a single-object delete expression, the deleted object is the object
129
+ denoted by the operand if its static type does not have a virtual
130
+ destructor, and its most-derived object otherwise.
131
+
132
+ [*Note 5*: If the deallocation function is not a destroying operator
133
+ delete and the deleted object is not the most derived object in the
134
+ former case, the behavior is undefined, as stated above. — *end note*]
135
+
136
+ For an array delete expression, the deleted object is the array object.
137
  When a *delete-expression* is executed, the selected deallocation
138
+ function shall be called with the address of the deleted object in a
139
+ single-object delete expression, or the address of the deleted object
140
+ suitably adjusted for the array allocation overhead [[expr.new]] in an
141
+ array delete expression, as its first argument.
142
+
143
+ [*Note 6*: Any cv-qualifiers in the type of the deleted object are
144
+ ignored when forming this argument. — *end note*]
145
+
146
+ If a destroying operator delete is used, an unspecified value is passed
147
+ as the argument corresponding to the parameter of type
148
+ `std::destroying_delete_t`. If a deallocation function with a parameter
149
  of type `std::align_val_t` is used, the alignment of the type of the
150
+ deleted object is passed as the corresponding argument. If a
151
  deallocation function with a parameter of type `std::size_t` is used,
152
+ the size of the deleted object in a single-object delete expression, or
153
+ of the array plus allocation overhead in an array delete expression, is
154
+ passed as the corresponding argument.
155
 
156
+ [*Note 7*: If this results in a call to a replaceable deallocation
157
+ function, and either the first argument was not the result of a prior
158
+ call to a replaceable allocation function or the second or third
159
+ argument was not the corresponding argument in said call, the behavior
160
+ is undefined ([[new.delete.single]],
161
+ [[new.delete.array]]). — *end note*]
162
 
163
  Access and ambiguity control are done for both the deallocation function
164
+ and the destructor ([[class.dtor]], [[class.free]]).
165