From Jason Turner

[expr.delete]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp76qla23h/{from.md → to.md} +64 -42
tmp/tmp76qla23h/{from.md → to.md} RENAMED
@@ -10,26 +10,32 @@ delete-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
 
@@ -37,17 +43,17 @@ match the type of the object allocated by `new`, not the syntax of the
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.
52
 
53
  If the object being deleted has incomplete class type at the point of
@@ -88,61 +94,78 @@ exception. — *end note*]
88
 
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
@@ -151,15 +174,14 @@ 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
 
 
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]
16
+
17
+ The operand shall be of pointer to object type or of class type. If of
18
+ class type, the operand is contextually implicitly converted [[conv]] to
19
+ a pointer to object type.[^26]
20
+
21
+ The *delete-expression* has type `void`.
22
 
23
  If the operand has a class type, the operand is converted to a pointer
24
  type by calling the above-mentioned conversion function, and the
25
  converted operand is used in place of the original operand for the
26
  remainder of this subclause. In a single-object delete expression, the
27
  value of the operand of `delete` may be a null pointer value, a pointer
28
+ value that resulted from a previous non-array *new-expression*, or a
29
+ pointer to a base class subobject of an object created by such a
30
+ *new-expression*. If not, the behavior is undefined. In an array delete
31
+ expression, the value of the operand of `delete` may be a null pointer
32
+ value or a pointer value that resulted from a previous array
33
+ *new-expression* whose allocation function was not a non-allocating form
34
+ [[new.delete.placement]].[^27]
35
+
36
+ If not, the behavior is undefined.
37
 
38
  [*Note 1*: This means that the syntax of the *delete-expression* must
39
  match the type of the object allocated by `new`, not the syntax of the
40
  *new-expression*. — *end note*]
41
 
 
43
  *delete-expression*; it is not necessary to cast away the constness
44
  [[expr.const.cast]] of the pointer expression before it is used as the
45
  operand of the *delete-expression*. — *end note*]
46
 
47
  In a single-object delete expression, if the static type of the object
48
+ to be deleted is not similar [[conv.qual]] to its dynamic type and the
49
+ selected deallocation function (see below) is not a destroying operator
50
+ delete, the static type shall be a base class of the dynamic type of the
51
+ object to be deleted and the static type shall have a virtual destructor
52
+ or the behavior is undefined. In an array delete expression, if the
53
+ dynamic type of the object to be deleted is not similar to its static
54
+ type, the behavior is undefined.
55
 
56
  The *cast-expression* in a *delete-expression* shall be evaluated
57
  exactly once.
58
 
59
  If the object being deleted has incomplete class type at the point of
 
94
 
95
  If the value of the operand of the *delete-expression* is a null pointer
96
  value, it is unspecified whether a deallocation function will be called
97
  as described above.
98
 
99
+ If a deallocation function is called, it is `operator delete` for a
100
+ single-object delete expression or `operator delete[]` for an array
101
+ delete expression.
 
 
 
102
 
103
+ [*Note 4*: An implementation provides default definitions of the
104
+ global deallocation functions
105
+ [[new.delete.single]], [[new.delete.array]]. A C++ program can provide
106
+ alternative definitions of these functions [[replacement.functions]],
107
+ and/or class-specific versions [[class.free]]. *end note*]
 
108
 
109
+ If the keyword `delete` in a *delete-expression* is not preceded by the
110
+ unary `::` operator and the type of the operand is a pointer to a
111
+ (possibly cv-qualified) class type `T` or (possibly multidimensional)
112
+ array thereof:
113
+
114
+ - For a single-object delete expression, if the operand is a pointer to
115
+ cv `T` and `T` has a virtual destructor, the deallocation function is
116
+ the one selected at the point of definition of the dynamic type’s
117
+ virtual destructor [[class.dtor]].
118
+ - Otherwise, a search is performed for the deallocation function’s name
119
+ in the scope of `T`.
120
+
121
+ Otherwise, or if nothing is found, the deallocation function’s name is
122
+ looked up by searching for it in the global scope. In any case, any
123
+ declarations other than of usual deallocation functions
124
+ [[basic.stc.dynamic.deallocation]] are discarded.
125
+
126
+ [*Note 5*: If only a placement deallocation function is found in a
127
+ class, the program is ill-formed because the lookup set is empty
128
+ [[basic.lookup]]. — *end note*]
129
+
130
+ If more than one deallocation function is found, the function to be
131
+ called is selected as follows:
132
 
133
  - If any of the deallocation functions is a destroying operator delete,
134
  all deallocation functions that are not destroying operator deletes
135
  are eliminated from further consideration.
136
  - If the type has new-extended alignment, a function with a parameter of
137
  type `std::align_val_t` is preferred; otherwise a function without
138
  such a parameter is preferred. If any preferred functions are found,
139
  all non-preferred functions are eliminated from further consideration.
140
  - If exactly one function remains, that function is selected and the
141
  selection process terminates.
142
+ - If the deallocation functions belong to a class scope, the one without
143
+ a parameter of type `std::size_t` is selected.
144
  - If the type is complete and if, for an array delete expression only,
145
  the operand is a pointer to a class type with a non-trivial destructor
146
+ or a (possibly multidimensional) array thereof, the function with a
147
  parameter of type `std::size_t` is selected.
148
  - Otherwise, it is unspecified whether a deallocation function with a
149
  parameter of type `std::size_t` is selected.
150
 
151
  For a single-object delete expression, the deleted object is the object
152
+ A pointed to by the operand if the static type of A does not have a
153
+ virtual destructor, and the most-derived object of A otherwise.
154
 
155
+ [*Note 6*: If the deallocation function is not a destroying operator
156
  delete and the deleted object is not the most derived object in the
157
  former case, the behavior is undefined, as stated above. — *end note*]
158
 
159
  For an array delete expression, the deleted object is the array object.
160
  When a *delete-expression* is executed, the selected deallocation
161
  function shall be called with the address of the deleted object in a
162
  single-object delete expression, or the address of the deleted object
163
  suitably adjusted for the array allocation overhead [[expr.new]] in an
164
  array delete expression, as its first argument.
165
 
166
+ [*Note 7*: Any cv-qualifiers in the type of the deleted object are
167
  ignored when forming this argument. — *end note*]
168
 
169
  If a destroying operator delete is used, an unspecified value is passed
170
  as the argument corresponding to the parameter of type
171
  `std::destroying_delete_t`. If a deallocation function with a parameter
 
174
  deallocation function with a parameter of type `std::size_t` is used,
175
  the size of the deleted object in a single-object delete expression, or
176
  of the array plus allocation overhead in an array delete expression, is
177
  passed as the corresponding argument.
178
 
179
+ [*Note 8*: If this results in a call to a replaceable deallocation
180
  function, and either the first argument was not the result of a prior
181
  call to a replaceable allocation function or the second or third
182
  argument was not the corresponding argument in said call, the behavior
183
+ is undefined [[new.delete.single]], [[new.delete.array]]. — *end note*]
 
184
 
185
  Access and ambiguity control are done for both the deallocation function
186
+ and the destructor [[class.dtor]], [[class.free]].
187