From Jason Turner

[expr.new]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmplv4c0lhs/{from.md → to.md} +120 -59
tmp/tmplv4c0lhs/{from.md → to.md} RENAMED
@@ -112,35 +112,43 @@ denotes an array type), the *new-expression* yields a pointer to the
112
  initial element (if any) of the array. both `new int` and `new int[10]`
113
  have type `int*` and the type of `new int[i][10]` is `int (*)[10]` The
114
  *attribute-specifier-seq* in a *noptr-new-declarator* appertains to the
115
  associated array type.
116
 
117
- Every *constant-expression* in a *noptr-new-declarator* shall be an
118
- integral constant expression ([[expr.const]]) and evaluate to a
119
- strictly positive value. The *expression* in a *noptr-new-declarator*
120
- shall be of integral type, unscoped enumeration type, or a class type
121
- for which a single non-explicit conversion function to integral or
122
- unscoped enumeration type exists ([[class.conv]]). If the expression is
123
- of class type, the expression is converted by calling that conversion
124
- function, and the result of the conversion is used in place of the
125
- original expression. given the definition `int n = 42`,
126
- `new float[n][5]` is well-formed (because `n` is the *expression* of a
127
- *noptr-new-declarator*), but `new float[5][n]` is ill-formed (because
128
- `n` is not a constant expression).
129
 
130
- When the value of the *expression* in a *noptr-new-declarator* is zero,
131
- the allocation function is called to allocate an array with no elements.
132
- If the value of that *expression* is less than zero or such that the
133
- size of the allocated object would exceed the implementation-defined
134
- limit, or if the *new-initializer* is a *braced-init-list* for which the
135
- number of *initializer-clause*s exceeds the number of elements to
136
- initialize, no storage is obtained and the *new-expression* terminates
137
- by throwing an exception of a type that would match a handler (
138
- [[except.handle]]) of type `std::bad_array_new_length` (
139
- [[new.badlength]]).
140
 
141
- A *new-expression* obtains storage for the object by calling an
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142
  *allocation function* ([[basic.stc.dynamic.allocation]]). If the
143
  *new-expression* terminates by throwing an exception, it may release
144
  storage by calling a deallocation function (
145
  [[basic.stc.dynamic.deallocation]]). If the allocated type is a
146
  non-array type, the allocation function’s name is `operator new` and the
@@ -158,24 +166,76 @@ allocation function’s name is looked up in the global scope. Otherwise,
158
  if the allocated type is a class type `T` or array thereof, the
159
  allocation function’s name is looked up in the scope of `T`. If this
160
  lookup fails to find the name, or if the allocated type is not a class
161
  type, the allocation function’s name is looked up in the global scope.
162
 
163
- A *new-expression* passes the amount of space requested to the
164
- allocation function as the first argument of type `std::size_t`. That
165
- argument shall be no less than the size of the object being created; it
166
- may be greater than the size of the object being created only if the
167
- object is an array. For arrays of `char` and `unsigned char`, the
168
- difference between the result of the *new-expression* and the address
169
- returned by the allocation function shall be an integral multiple of the
170
- strictest fundamental alignment requirement ([[basic.align]]) of any
171
- object type whose size is no greater than the size of the array being
172
- created. Because allocation functions are assumed to return pointers to
173
- storage that is appropriately aligned for objects of any type with
174
- fundamental alignment, this constraint on array allocation overhead
175
- permits the common idiom of allocating character arrays into which
176
- objects of other types will later be placed.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
 
178
  The *new-placement* syntax is used to supply additional arguments to an
179
  allocation function. If used, overload resolution is performed on a
180
  function call created by assembling an argument list consisting of the
181
  amount of space requested (the first argument) and the expressions in
@@ -220,12 +280,12 @@ necessarily be the same as that of the block if the object is an array.
220
 
221
  A *new-expression* that creates an object of type `T` initializes that
222
  object as follows:
223
 
224
  - If the *new-initializer* is omitted, the object is
225
- default-initialized ([[dcl.init]]); if no initialization is
226
- performed, the object has indeterminate value.
227
  - Otherwise, the *new-initializer* is interpreted according to the
228
  initialization rules of  [[dcl.init]] for direct-initialization.
229
 
230
  The invocation of the allocation function is indeterminately sequenced
231
  with respect to the evaluations of expressions in the *new-initializer*.
@@ -235,23 +295,24 @@ expressions in the *new-initializer* are evaluated if the allocation
235
  function returns the null pointer or exits using an exception.
236
 
237
  If the *new-expression* creates an object or an array of objects of
238
  class type, access and ambiguity control are done for the allocation
239
  function, the deallocation function ([[class.free]]), and the
240
- constructor ([[class.ctor]]). If the new expression creates an array of
241
- objects of class type, access and ambiguity control are done for the
242
- destructor ([[class.dtor]]).
243
 
244
  If any part of the object initialization described above[^19] terminates
245
- by throwing an exception and a suitable deallocation function can be
246
- found, the deallocation function is called to free the memory in which
247
- the object was being constructed, after which the exception continues to
248
- propagate in the context of the *new-expression*. If no unambiguous
249
- matching deallocation function can be found, propagating the exception
250
- does not cause the object’s memory to be freed. This is appropriate when
251
- the called allocation function does not allocate memory; otherwise, it
252
- is likely to result in a memory leak.
 
253
 
254
  If the *new-expression* begins with a unary `::` operator, the
255
  deallocation function’s name is looked up in the global scope.
256
  Otherwise, if the allocated type is a class type `T` or an array
257
  thereof, the deallocation function’s name is looked up in the scope of
@@ -260,19 +321,19 @@ not a class type or array thereof, the deallocation function’s name is
260
  looked up in the global scope.
261
 
262
  A declaration of a placement deallocation function matches the
263
  declaration of a placement allocation function if it has the same number
264
  of parameters and, after parameter transformations ([[dcl.fct]]), all
265
- parameter types except the first are identical. Any non-placement
266
- deallocation function matches a non-placement allocation function. If
267
- the lookup finds a single matching deallocation function, that function
268
- will be called; otherwise, no deallocation function will be called. If
269
- the lookup finds the two-parameter form of a usual deallocation
270
- function ([[basic.stc.dynamic.deallocation]]) and that function,
271
- considered as a placement deallocation function, would have been
272
- selected as a match for the allocation function, the program is
273
- ill-formed.
274
 
275
  ``` cpp
276
  struct S {
277
  // Placement allocation function:
278
  static void* operator new(std::size_t, std::size_t);
 
112
  initial element (if any) of the array. both `new int` and `new int[10]`
113
  have type `int*` and the type of `new int[i][10]` is `int (*)[10]` The
114
  *attribute-specifier-seq* in a *noptr-new-declarator* appertains to the
115
  associated array type.
116
 
117
+ Every *constant-expression* in a *noptr-new-declarator* shall be a
118
+ converted constant expression ([[expr.const]]) of type `std::size_t`
119
+ and shall evaluate to a strictly positive value. The *expression* in a
120
+ *noptr-new-declarator*is implicitly converted to `std::size_t`. given
121
+ the definition `int n = 42`, `new float[n][5]` is well-formed (because
122
+ `n` is the *expression* of a *noptr-new-declarator*), but
123
+ `new float[5][n]` is ill-formed (because `n` is not a constant
124
+ expression).
 
 
 
 
125
 
126
+ The *expression* in a *noptr-new-declarator* is erroneous if:
 
 
 
 
 
 
 
 
 
127
 
128
+ - the expression is of non-class type and its value before converting to
129
+ `std::size_t` is less than zero;
130
+ - the expression is of class type and its value before application of
131
+ the second standard conversion ([[over.ics.user]])[^18] is less than
132
+ zero;
133
+ - its value is such that the size of the allocated object would exceed
134
+ the implementation-defined limit (annex  [[implimits]]); or
135
+ - the *new-initializer* is a *braced-init-list* and the number of array
136
+ elements for which initializers are provided (including the
137
+ terminating `'\0'` in a string literal ([[lex.string]])) exceeds the
138
+ number of elements to initialize.
139
+
140
+ If the *expression*, after converting to `std::size_t`, is a core
141
+ constant expression and the expression is erroneous, the program is
142
+ ill-formed. Otherwise, a *new-expression* with an erroneous expression
143
+ does not call an allocation function and terminates by throwing an
144
+ exception of a type that would match a handler ([[except.handle]]) of
145
+ type `std::bad_array_new_length` ([[new.badlength]]). When the value of
146
+ the *expression* is zero, the allocation function is called to allocate
147
+ an array with no elements.
148
+
149
+ A *new-expression* may obtain storage for the object by calling an
150
  *allocation function* ([[basic.stc.dynamic.allocation]]). If the
151
  *new-expression* terminates by throwing an exception, it may release
152
  storage by calling a deallocation function (
153
  [[basic.stc.dynamic.deallocation]]). If the allocated type is a
154
  non-array type, the allocation function’s name is `operator new` and the
 
166
  if the allocated type is a class type `T` or array thereof, the
167
  allocation function’s name is looked up in the scope of `T`. If this
168
  lookup fails to find the name, or if the allocated type is not a class
169
  type, the allocation function’s name is looked up in the global scope.
170
 
171
+ An implementation is allowed to omit a call to a replaceable global
172
+ allocation function ([[new.delete.single]], [[new.delete.array]]). When
173
+ it does so, the storage is instead provided by the implementation or
174
+ provided by extending the allocation of another *new-expression*. The
175
+ implementation may extend the allocation of a *new-expression* `e1` to
176
+ provide storage for a *new-expression* `e2` if the following would be
177
+ true were the allocation not extended:
178
+
179
+ - the evaluation of `e1` is sequenced before the evaluation of `e2`, and
180
+ - `e2` is evaluated whenever `e1` obtains storage, and
181
+ - both `e1` and `e2` invoke the same replaceable global allocation
182
+ function, and
183
+ - if the allocation function invoked by `e1` and `e2` is throwing, any
184
+ exceptions thrown in the evaluation of either `e1` or `e2` would be
185
+ first caught in the same handler, and
186
+ - the pointer values produced by `e1` and `e2` are operands to evaluated
187
+ *delete-expression*s, and
188
+ - the evaluation of `e2` is sequenced before the evaluation of the
189
+ *delete-expression* whose operand is the pointer value produced by
190
+ `e1`.
191
+
192
+ ``` cpp
193
+ void mergeable(int x) {
194
+ // These allocations are safe for merging:
195
+ std::unique_ptr<char[]> a{new (std::nothrow) char[8]};
196
+ std::unique_ptr<char[]> b{new (std::nothrow) char[8]};
197
+ std::unique_ptr<char[]> c{new (std::nothrow) char[x]};
198
+
199
+ g(a.get(), b.get(), c.get());
200
+ }
201
+
202
+ void unmergeable(int x) {
203
+ std::unique_ptr<char[]> a{new char[8]};
204
+ try {
205
+ // Merging this allocation would change its catch handler.
206
+ std::unique_ptr<char[]> b{new char[x]};
207
+ } catch (const std::bad_alloc& e) {
208
+ std::cerr << "Allocation failed: " << e.what() << std::endl;
209
+ throw;
210
+ }
211
+ }
212
+ ```
213
+
214
+ When a *new-expression* calls an allocation function and that allocation
215
+ has not been extended, the *new-expression* passes the amount of space
216
+ requested to the allocation function as the first argument of type
217
+ `std::size_t`. That argument shall be no less than the size of the
218
+ object being created; it may be greater than the size of the object
219
+ being created only if the object is an array. For arrays of `char` and
220
+ `unsigned char`, the difference between the result of the
221
+ *new-expression* and the address returned by the allocation function
222
+ shall be an integral multiple of the strictest fundamental alignment
223
+ requirement ([[basic.align]]) of any object type whose size is no
224
+ greater than the size of the array being created. Because allocation
225
+ functions are assumed to return pointers to storage that is
226
+ appropriately aligned for objects of any type with fundamental
227
+ alignment, this constraint on array allocation overhead permits the
228
+ common idiom of allocating character arrays into which objects of other
229
+ types will later be placed.
230
+
231
+ When a *new-expression* calls an allocation function and that allocation
232
+ has been extended, the size argument to the allocation call shall be no
233
+ greater than the sum of the sizes for the omitted calls as specified
234
+ above, plus the size for the extended call had it not been extended,
235
+ plus any padding necessary to align the allocated objects within the
236
+ allocated memory.
237
 
238
  The *new-placement* syntax is used to supply additional arguments to an
239
  allocation function. If used, overload resolution is performed on a
240
  function call created by assembling an argument list consisting of the
241
  amount of space requested (the first argument) and the expressions in
 
280
 
281
  A *new-expression* that creates an object of type `T` initializes that
282
  object as follows:
283
 
284
  - If the *new-initializer* is omitted, the object is
285
+ default-initialized ([[dcl.init]]). If no initialization is
286
+ performed, the object has an indeterminate value.
287
  - Otherwise, the *new-initializer* is interpreted according to the
288
  initialization rules of  [[dcl.init]] for direct-initialization.
289
 
290
  The invocation of the allocation function is indeterminately sequenced
291
  with respect to the evaluations of expressions in the *new-initializer*.
 
295
  function returns the null pointer or exits using an exception.
296
 
297
  If the *new-expression* creates an object or an array of objects of
298
  class type, access and ambiguity control are done for the allocation
299
  function, the deallocation function ([[class.free]]), and the
300
+ constructor ([[class.ctor]]). If the *new-expression* creates an array
301
+ of objects of class type, the destructor is potentially invoked (
302
+ [[class.dtor]]).
303
 
304
  If any part of the object initialization described above[^19] terminates
305
+ by throwing an exception, storage has been obtained for the object, and
306
+ a suitable deallocation function can be found, the deallocation function
307
+ is called to free the memory in which the object was being constructed,
308
+ after which the exception continues to propagate in the context of the
309
+ *new-expression*. If no unambiguous matching deallocation function can
310
+ be found, propagating the exception does not cause the object’s memory
311
+ to be freed. This is appropriate when the called allocation function
312
+ does not allocate memory; otherwise, it is likely to result in a memory
313
+ leak.
314
 
315
  If the *new-expression* begins with a unary `::` operator, the
316
  deallocation function’s name is looked up in the global scope.
317
  Otherwise, if the allocated type is a class type `T` or an array
318
  thereof, the deallocation function’s name is looked up in the scope of
 
321
  looked up in the global scope.
322
 
323
  A declaration of a placement deallocation function matches the
324
  declaration of a placement allocation function if it has the same number
325
  of parameters and, after parameter transformations ([[dcl.fct]]), all
326
+ parameter types except the first are identical. If the lookup finds a
327
+ single matching deallocation function, that function will be called;
328
+ otherwise, no deallocation function will be called. If the lookup finds
329
+ the two-parameter form of a usual deallocation function (
330
+ [[basic.stc.dynamic.deallocation]]) and that function, considered as a
331
+ placement deallocation function, would have been selected as a match for
332
+ the allocation function, the program is ill-formed. For a non-placement
333
+ allocation function, the normal deallocation function lookup is used to
334
+ find the matching deallocation function ([[expr.delete]])
335
 
336
  ``` cpp
337
  struct S {
338
  // Placement allocation function:
339
  static void* operator new(std::size_t, std::size_t);