This commit is contained in:
2025-10-25 03:02:53 +03:00
commit 043225d523
3416 changed files with 681196 additions and 0 deletions

667
cppdraft/expr/new.md Normal file
View File

@@ -0,0 +1,667 @@
[expr.new]
# 7 Expressions [[expr]](./#expr)
## 7.6 Compound expressions [[expr.compound]](expr.compound#expr.new)
### 7.6.2 Unary expressions [[expr.unary]](expr.unary#expr.new)
#### 7.6.2.8 New [expr.new]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L5752)
The [*new-expression*](#nt:new-expression "7.6.2.8New[expr.new]") attempts to create an object of the[*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]") or [*new-type-id*](#nt:new-type-id "7.6.2.8New[expr.new]") ([[dcl.name]](dcl.name "9.3.2Type names")) to which
it is applied[.](#1.sentence-1)
The type of that object is the [*allocated type*](#def:type,allocated "7.6.2.8New[expr.new]")[.](#1.sentence-2)
This type shall be a complete object type ([[basic.types.general]](basic.types.general#term.incomplete.type "6.9.1General")),
but not an abstract class type ([[class.abstract]](class.abstract "11.7.4Abstract classes")) or array
thereof ([[intro.object]](intro.object "6.8.2Object model"))[.](#1.sentence-3)
[*Note [1](#note-1)*:
Because references are not objects, references cannot be created by[*new-expression*](#nt:new-expression "7.6.2.8New[expr.new]")*s*[.](#1.sentence-4)
— *end note*]
[*Note [2](#note-2)*:
The [*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]") can be a cv-qualified type, in which case the
object created by the [*new-expression*](#nt:new-expression "7.6.2.8New[expr.new]") has a cv-qualified type[.](#1.sentence-5)
— *end note*]
[new-expression:](#nt:new-expression "7.6.2.8New[expr.new]")
::opt new [*new-placement*](#nt:new-placement "7.6.2.8New[expr.new]")opt [*new-type-id*](#nt:new-type-id "7.6.2.8New[expr.new]") [*new-initializer*](#nt:new-initializer "7.6.2.8New[expr.new]")opt
::opt new [*new-placement*](#nt:new-placement "7.6.2.8New[expr.new]")opt ( [*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]") ) [*new-initializer*](#nt:new-initializer "7.6.2.8New[expr.new]")opt
[new-placement:](#nt:new-placement "7.6.2.8New[expr.new]")
( [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1General[expr.post.general]") )
[new-type-id:](#nt:new-type-id "7.6.2.8New[expr.new]")
[*type-specifier-seq*](dcl.type.general#nt:type-specifier-seq "9.2.9.1General[dcl.type.general]") [*new-declarator*](#nt:new-declarator "7.6.2.8New[expr.new]")opt
[new-declarator:](#nt:new-declarator "7.6.2.8New[expr.new]")
[*ptr-operator*](dcl.decl.general#nt:ptr-operator "9.3.1General[dcl.decl.general]") [*new-declarator*](#nt:new-declarator "7.6.2.8New[expr.new]")opt
[*noptr-new-declarator*](#nt:noptr-new-declarator "7.6.2.8New[expr.new]")
[noptr-new-declarator:](#nt:noptr-new-declarator "7.6.2.8New[expr.new]")
[ [*expression*](expr.comma#nt:expression "7.6.20Comma operator[expr.comma]")opt ] [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt
[*noptr-new-declarator*](#nt:noptr-new-declarator "7.6.2.8New[expr.new]") [ [*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") ] [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt
[new-initializer:](#nt:new-initializer "7.6.2.8New[expr.new]")
( [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1General[expr.post.general]")opt )
[*braced-init-list*](dcl.init.general#nt:braced-init-list "9.5.1General[dcl.init.general]")
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L5813)
If a [placeholder type](dcl.spec.auto "9.2.9.7Placeholder type specifiers[dcl.spec.auto]") or
a placeholder for a deduced class type ([[dcl.type.class.deduct]](dcl.type.class.deduct "9.2.9.8Deduced class template specialization types"))
appears in the[*type-specifier-seq*](dcl.type.general#nt:type-specifier-seq "9.2.9.1General[dcl.type.general]") of a [*new-type-id*](#nt:new-type-id "7.6.2.8New[expr.new]") or[*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]") of a [*new-expression*](#nt:new-expression "7.6.2.8New[expr.new]"),
the allocated type is deduced as follows:
Let*init* be the [*new-initializer*](#nt:new-initializer "7.6.2.8New[expr.new]"), if any,
andT be the [*new-type-id*](#nt:new-type-id "7.6.2.8New[expr.new]") or [*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]") of
the [*new-expression*](#nt:new-expression "7.6.2.8New[expr.new]"), then the allocated type is the type
deduced for the variable x in the invented
declaration ([[dcl.spec.auto]](dcl.spec.auto "9.2.9.7Placeholder type specifiers")):T x *init* ;
[*Example [1](#example-1)*: new auto(1); // allocated type is intauto x = new auto('a'); // allocated type is char, x is of type char*template<class T> struct A { A(T, T); };auto y = new A{1, 2}; // allocated type is A<int> — *end example*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L5841)
The [*new-type-id*](#nt:new-type-id "7.6.2.8New[expr.new]") in a [*new-expression*](#nt:new-expression "7.6.2.8New[expr.new]") is the longest
possible sequence of [*new-declarator*](#nt:new-declarator "7.6.2.8New[expr.new]")*s*[.](#3.sentence-1)
[*Note [3](#note-3)*:
This prevents ambiguities between the declarator operators &, &&,*, and [] and their expression counterparts[.](#3.sentence-2)
— *end note*]
[*Example [2](#example-2)*: new int * i; // syntax error: parsed as (new int*) i, not as (new int)*i
The * is the pointer declarator and not the multiplication
operator[.](#3.sentence-3)
— *end example*]
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L5856)
[*Note [4](#note-4)*:
Parentheses in a [*new-type-id*](#nt:new-type-id "7.6.2.8New[expr.new]") of a [*new-expression*](#nt:new-expression "7.6.2.8New[expr.new]") can have surprising effects[.](#4.sentence-1)
[*Example [3](#example-3)*:
new int(*[10])(); // error is ill-formed because the binding is(new int) (*[10])(); // error
Instead, the explicitly parenthesized version of the new operator can be used to create objects of compound
types ([[basic.compound]](basic.compound "6.9.4Compound types")):
new (int (*[10])()); allocates an array of 10 pointers to functions (taking no
argument and returning int)[.](#4.sentence-4)
— *end example*]
— *end note*]
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L5882)
The [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") in a [*noptr-new-declarator*](#nt:noptr-new-declarator "7.6.2.8New[expr.new]") appertains
to the associated array type[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L5886)
Every [*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") in a[*noptr-new-declarator*](#nt:noptr-new-declarator "7.6.2.8New[expr.new]") shall be a converted constant
expression ([[expr.const]](expr.const "7.7Constant expressions")) of type std::size_t and
its value shall be greater than zero[.](#6.sentence-1)
[*Example [4](#example-4)*:
Given the definition int n = 42,new float[n][5] is well-formed (because n is the[*expression*](expr.comma#nt:expression "7.6.20Comma operator[expr.comma]") of a [*noptr-new-declarator*](#nt:noptr-new-declarator "7.6.2.8New[expr.new]")), butnew float[5][n] is ill-formed (because n is not a
constant expression)[.](#6.sentence-2)
Furthermore,new float[0] is well-formed
(because 0 is the [*expression*](expr.comma#nt:expression "7.6.20Comma operator[expr.comma]") of a [*noptr-new-declarator*](#nt:noptr-new-declarator "7.6.2.8New[expr.new]"),
where a value of zero results in the allocation of an array with no elements),
but new float[n][0] is ill-formed
(because 0 is the [*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") of a [*noptr-new-declarator*](#nt:noptr-new-declarator "7.6.2.8New[expr.new]"),
where only values greater than zero are allowed)[.](#6.sentence-3)
— *end example*]
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L5908)
If the [*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]") or [*new-type-id*](#nt:new-type-id "7.6.2.8New[expr.new]") denotes an array type of unknown bound ([[dcl.array]](dcl.array "9.3.4.5Arrays")),
the [*new-initializer*](#nt:new-initializer "7.6.2.8New[expr.new]") shall not be omitted;
the allocated object is an array with n elements,
where n is determined from the number of initial elements
supplied in
the [*new-initializer*](#nt:new-initializer "7.6.2.8New[expr.new]") ([[dcl.init.aggr]](dcl.init.aggr "9.5.2Aggregates"), [[dcl.init.string]](dcl.init.string "9.5.3Character arrays"))[.](#7.sentence-1)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L5917)
If the [*expression*](expr.comma#nt:expression "7.6.20Comma operator[expr.comma]") in a [*noptr-new-declarator*](#nt:noptr-new-declarator "7.6.2.8New[expr.new]") is present, it is implicitly converted to std::size_t[.](#8.sentence-1)
The value of the [*expression*](expr.comma#nt:expression "7.6.20Comma operator[expr.comma]") is invalid if
- [(8.1)](#8.1)
the expression is of non-class type and its value before converting tostd::size_t is less than zero;
- [(8.2)](#8.2)
the expression is of class type and its value before application of the second
standard conversion ([[over.ics.user]](over.ics.user "12.2.4.2.3User-defined conversion sequences"))[59](#footnote-59 "If the conversion function returns a signed integer type, the second standard conversion converts to the unsigned type std::size_­t and thus thwarts any attempt to detect a negative value afterwards.") is less than zero;
- [(8.3)](#8.3)
its value is such that the size of the allocated object would exceed theimplementation-defined [limit](implimits "Annex B(informative)Implementation quantities[implimits]"); or
- [(8.4)](#8.4)
the [*new-initializer*](#nt:new-initializer "7.6.2.8New[expr.new]") is a [*braced-init-list*](dcl.init.general#nt:braced-init-list "9.5.1General[dcl.init.general]") and the
number of array elements for which initializers are provided (including the
terminating '\0' in a [*string-literal*](lex.string#nt:string-literal "5.13.5String literals[lex.string]") ([[lex.string]](lex.string "5.13.5String literals"))) exceeds the
number of elements to initialize[.](#8.sentence-2)
If the value of the [*expression*](expr.comma#nt:expression "7.6.20Comma operator[expr.comma]") is invalid after converting to std::size_t:
- [(8.5)](#8.5)
if the [*expression*](expr.comma#nt:expression "7.6.20Comma operator[expr.comma]") is a potentially-evaluated core constant expression,
the program is ill-formed;
- [(8.6)](#8.6)
otherwise, an allocation function is not called; instead
* [(8.6.1)](#8.6.1)
if the allocation function that would have been called
has a non-throwing exception specification ([[except.spec]](except.spec "14.5Exception specifications")),
the value of the [*new-expression*](#nt:new-expression "7.6.2.8New[expr.new]") is the null pointer value of the required result type;
* [(8.6.2)](#8.6.2)
otherwise, the [*new-expression*](#nt:new-expression "7.6.2.8New[expr.new]") terminates by throwing an
exception of a type that would match a handler ([[except.handle]](except.handle "14.4Handling an exception")) of type[std::bad_array_new_length](new.badlength "17.6.4.2Class bad_­array_­new_­length[new.badlength]")[.](#8.sentence-3)
When the value of the [*expression*](expr.comma#nt:expression "7.6.20Comma operator[expr.comma]") is zero, the allocation
function is called to allocate an array with no elements[.](#8.sentence-4)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L5972)
If the allocated type is an array,
the [*new-initializer*](#nt:new-initializer "7.6.2.8New[expr.new]") is a [*braced-init-list*](dcl.init.general#nt:braced-init-list "9.5.1General[dcl.init.general]"), and
the [*expression*](expr.comma#nt:expression "7.6.20Comma operator[expr.comma]") is potentially-evaluated and not a core constant expression,
the semantic constraints of copy-initializing a hypothetical element of
the array from an empty initializer list
are checked ([[dcl.init.list]](dcl.init.list "9.5.5List-initialization"))[.](#9.sentence-1)
[*Note [5](#note-5)*:
The array can contain more elements than there are
elements in the [*braced-init-list*](dcl.init.general#nt:braced-init-list "9.5.1General[dcl.init.general]"),
requiring initialization of the remainder of the array elements from
an empty initializer list[.](#9.sentence-2)
— *end note*]
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L5987)
Objects created by a [*new-expression*](#nt:new-expression "7.6.2.8New[expr.new]") have dynamic storage
duration ([[basic.stc.dynamic]](basic.stc.dynamic "6.8.6.5Dynamic storage duration"))[.](#10.sentence-1)
[*Note [6](#note-6)*:
The lifetime of such an object is not necessarily restricted to the
scope in which it is created[.](#10.sentence-2)
— *end note*]
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L5997)
When the allocated type is “array of N T”
(that is, the [*noptr-new-declarator*](#nt:noptr-new-declarator "7.6.2.8New[expr.new]") syntax is used or the[*new-type-id*](#nt:new-type-id "7.6.2.8New[expr.new]") or [*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]") denotes an array type),
the [*new-expression*](#nt:new-expression "7.6.2.8New[expr.new]") yields a prvalue of type “pointer to T”
that points to the initial element (if any) of the array[.](#11.sentence-1)
Otherwise, let T be the allocated type;
the [*new-expression*](#nt:new-expression "7.6.2.8New[expr.new]") is a prvalue of type “pointer to T”
that points to the object created[.](#11.sentence-2)
[*Note [7](#note-7)*:
Both new int and new int[10] have type int* and
the type of new int[i][10] is int (*)[10][.](#11.sentence-3)
— *end note*]
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L6013)
A [*new-expression*](#nt:new-expression "7.6.2.8New[expr.new]") may obtain storage for the object by calling an
allocation function ([[basic.stc.dynamic.allocation]](basic.stc.dynamic.allocation "6.8.6.5.2Allocation functions"))[.](#12.sentence-1)
If
the [*new-expression*](#nt:new-expression "7.6.2.8New[expr.new]") terminates by throwing an exception, it
may release storage by calling a [deallocation
function](basic.stc.dynamic.deallocation "6.8.6.5.3Deallocation functions[basic.stc.dynamic.deallocation]")[.](#12.sentence-2)
If the allocated type
is a non-array type, the allocation function's name isoperator new and the deallocation function's name isoperator delete[.](#12.sentence-3)
If the allocated type is an array type, the
allocation function's name isoperator new[] and the deallocation function's name isoperator delete[][.](#12.sentence-4)
[*Note [8](#note-8)*:
An implementation is expected to provide default definitions for the global
allocation
functions ([[basic.stc.dynamic]](basic.stc.dynamic "6.8.6.5Dynamic storage duration"), [[new.delete.single]](new.delete.single "17.6.3.2Single-object forms"), [[new.delete.array]](new.delete.array "17.6.3.3Array forms"))[.](#12.sentence-5)
A C++ program can provide alternative definitions of
these functions ([[replacement.functions]](replacement.functions "16.4.5.6Replacement functions")) and/or class-specific
versions ([[class.free]](class.free "11.4.11Allocation and deallocation functions"))[.](#12.sentence-6)
The set of allocation and deallocation functions that can be called
by a [*new-expression*](#nt:new-expression "7.6.2.8New[expr.new]") can include functions that do not perform allocation or deallocation;
for example, see [[new.delete.placement]](new.delete.placement "17.6.3.4Non-allocating forms")[.](#12.sentence-7)
— *end note*]
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L6043)
If the [*new-expression*](#nt:new-expression "7.6.2.8New[expr.new]") does not begin with a unary :: operator and
the allocated type is a class type T or array thereof,
a search is performed for the allocation function's name in the scope
of T ([[class.member.lookup]](class.member.lookup "6.5.2Member name lookup"))[.](#13.sentence-1)
Otherwise, or if nothing is found,
the allocation function's name is looked up by
searching for it in the global scope[.](#13.sentence-2)
[14](#14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L6054)
An implementation is allowed to omit a call to a replaceable global allocation
function ([[new.delete.single]](new.delete.single "17.6.3.2Single-object forms"), [[new.delete.array]](new.delete.array "17.6.3.3Array forms"))[.](#14.sentence-1)
When it does so,
the storage is instead provided by the implementation or provided by extending
the allocation of another [*new-expression*](#nt:new-expression "7.6.2.8New[expr.new]")[.](#14.sentence-2)
[15](#15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L6060)
During an evaluation of a constant expression,
a call to a replaceable allocation function is always omitted ([[expr.const]](expr.const "7.7Constant expressions"))[.](#15.sentence-1)
[16](#16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L6064)
The implementation may
extend the allocation of a [*new-expression*](#nt:new-expression "7.6.2.8New[expr.new]") e1 to provide
storage for a [*new-expression*](#nt:new-expression "7.6.2.8New[expr.new]") e2 if the
following would be true were the allocation not extended:
- [(16.1)](#16.1)
the evaluation of e1 is sequenced before the evaluation ofe2, and
- [(16.2)](#16.2)
e2 is evaluated whenever e1 obtains storage, and
- [(16.3)](#16.3)
both e1 and e2 invoke the same replaceable global
allocation function, and
- [(16.4)](#16.4)
if the allocation function invoked by e1 and e2 is
throwing, any exceptions thrown in the evaluation of either e1 ore2 would be first caught in the same handler, and
- [(16.5)](#16.5)
the pointer values produced by e1 and e2 are operands to
evaluated [*delete-expression*](expr.delete#nt:delete-expression "7.6.2.9Delete[expr.delete]")*s*, and
- [(16.6)](#16.6)
the evaluation of e2 is sequenced before the evaluation of the[*delete-expression*](expr.delete#nt:delete-expression "7.6.2.9Delete[expr.delete]") whose operand is the pointer value produced
by e1[.](#16.sentence-1)
[*Example [5](#example-5)*: void can_merge(int x) {// These allocations are safe for merging: std::unique_ptr<char[]> a{new (std::nothrow) char[8]};
std::unique_ptr<char[]> b{new (std::nothrow) char[8]};
std::unique_ptr<char[]> c{new (std::nothrow) char[x]};
g(a.get(), b.get(), c.get());}void cannot_merge(int x) { std::unique_ptr<char[]> a{new char[8]}; try {// Merging this allocation would change its catch handler. std::unique_ptr<char[]> b{new char[x]}; } catch (const std::bad_alloc& e) { std::cerr << "Allocation failed: " << e.what() << std::endl; throw; }} — *end example*]
[17](#17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L6114)
When a [*new-expression*](#nt:new-expression "7.6.2.8New[expr.new]") calls an allocation function and that
allocation has not been extended, the[*new-expression*](#nt:new-expression "7.6.2.8New[expr.new]") passes the amount of space requested to the
allocation function as the first argument of typestd::size_t[.](#17.sentence-1)
That argument shall be no less than the size
of the object being created; it may be greater than the size of the
object being created only if the object is an array and
the allocation function is not a non-allocating form ([[new.delete.placement]](new.delete.placement "17.6.3.4Non-allocating forms"))[.](#17.sentence-2)
For arrays ofchar, unsigned char, and std::byte,
the difference between the
result of the [*new-expression*](#nt:new-expression "7.6.2.8New[expr.new]") and the address returned by the
allocation function shall be an integral multiple of the
strictest fundamental[alignment requirement](basic.align "6.8.3Alignment[basic.align]") of any object type whose size
is no greater than the size of the array being created[.](#17.sentence-3)
[*Note [9](#note-9)*:
Because allocation functions are assumed to return pointers to storage
that is appropriately aligned for objects of any type
with fundamental alignment, this constraint
on array allocation overhead permits the common idiom of allocating
character arrays into which objects of other types will later be placed[.](#17.sentence-4)
— *end note*]
[18](#18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L6140)
When a [*new-expression*](#nt:new-expression "7.6.2.8New[expr.new]") calls an allocation function and that
allocation has been extended, the size argument to the allocation call shall
be no greater than the sum of the sizes for the omitted calls as specified
above, plus the size for the extended call had it not been extended, plus any
padding necessary to align the allocated objects within the allocated memory[.](#18.sentence-1)
[19](#19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L6147)
The [*new-placement*](#nt:new-placement "7.6.2.8New[expr.new]") syntax is used to supply additional
arguments to an allocation function; such an expression is called
a [*placement* ](#def:new-expression,placement "7.6.2.8New[expr.new]")*[*new-expression*](#nt:new-expression "7.6.2.8New[expr.new]")*[.](#19.sentence-1)
[20](#20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L6153)
Overload resolution is
performed on a function call created by assembling an argument list[.](#20.sentence-1)
The first argument is
the amount of space requested,
and has type std::size_t[.](#20.sentence-2)
If the type of the allocated object has new-extended alignment,
the next argument is
the type's alignment,
and has type std::align_val_t[.](#20.sentence-3)
If the [*new-placement*](#nt:new-placement "7.6.2.8New[expr.new]") syntax is used,
the [*initializer-clause*](dcl.init.general#nt:initializer-clause "9.5.1General[dcl.init.general]")*s* in its [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1General[expr.post.general]") are the succeeding arguments[.](#20.sentence-4)
If no matching function is found then
- [(20.1)](#20.1)
if the allocated object type has new-extended alignment,
the alignment argument is removed from the argument list;
- [(20.2)](#20.2)
otherwise, an argument that
is the type's alignment and has type std::align_val_t is added into the argument list immediately after the first argument;
and then overload resolution is performed again[.](#20.sentence-5)
[21](#21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L6181)
[*Example [6](#example-6)*:
- [(21.1)](#21.1)
new T results in one of the following calls:operator new(sizeof(T))operator new(sizeof(T), std::align_val_t(alignof(T)))
- [(21.2)](#21.2)
new(2,f) T results in one of the following calls:operator new(sizeof(T), 2, f)operator new(sizeof(T), std::align_val_t(alignof(T)), 2, f)
- [(21.3)](#21.3)
new T[5] results in one of the following calls:operator new[](sizeof(T) * 5 + x)operator new[](sizeof(T) * 5 + x, std::align_val_t(alignof(T)))
- [(21.4)](#21.4)
new(2,f) T[5] results in one of the following calls:operator new[](sizeof(T) * 5 + x, 2, f)operator new[](sizeof(T) * 5 + x, std::align_val_t(alignof(T)), 2, f)
Here, each instance of x is a non-negative unspecified value
representing array allocation overhead; the result of the[*new-expression*](#nt:new-expression "7.6.2.8New[expr.new]") will be offset by this amount from the value
returned by operator new[].
This overhead may be applied in all
array [*new-expression*](#nt:new-expression "7.6.2.8New[expr.new]")*s*, including those referencing
a placement allocation function, except when referencing
the library function operator new[](std::size_t, void*)[.](#21.sentence-1)
The amount of overhead may vary from one
invocation of new to another[.](#21.sentence-2)
— *end example*]
[22](#22)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L6216)
[*Note [10](#note-10)*:
Unless an allocation function has a non-throwing[exception specification](except.spec "14.5Exception specifications[except.spec]"),
it indicates failure to allocate storage by throwing astd::bad_alloc exception ([[basic.stc.dynamic.allocation]](basic.stc.dynamic.allocation "6.8.6.5.2Allocation functions"), [[except]](except "14Exception handling"), [[bad.alloc]](bad.alloc "17.6.4.1Class bad_­alloc"));
it returns a non-null pointer otherwise[.](#22.sentence-1)
If the allocation function
has a non-throwing exception specification,
it returns null to indicate failure to allocate storage
and a non-null pointer otherwise[.](#22.sentence-2)
— *end note*]
If the allocation function is a non-allocating
form ([[new.delete.placement]](new.delete.placement "17.6.3.4Non-allocating forms")) that returns null,
the behavior is undefined[.](#22.sentence-3)
Otherwise,
if the allocation function returns null, initialization shall not be
done, the deallocation function shall not be called, and the value of
the [*new-expression*](#nt:new-expression "7.6.2.8New[expr.new]") shall be null[.](#22.sentence-4)
[23](#23)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L6238)
[*Note [11](#note-11)*:
When the allocation function returns a value other than null, it must be
a pointer to a block of storage in which space for the object has been
reserved[.](#23.sentence-1)
The block of storage is assumed to be
appropriately aligned ([[basic.align]](basic.align "6.8.3Alignment"))
and of the requested size[.](#23.sentence-2)
The address of the created object will not
necessarily be the same as that of the block if the object is an array[.](#23.sentence-3)
— *end note*]
[24](#24)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L6248)
A [*new-expression*](#nt:new-expression "7.6.2.8New[expr.new]") that creates an object of type T initializes that object as follows:
- [(24.1)](#24.1)
If the [*new-initializer*](#nt:new-initializer "7.6.2.8New[expr.new]") is omitted, the object is
default-initialized ([[dcl.init]](dcl.init "9.5Initializers"))[.](#24.1.sentence-1)
[*Note [12](#note-12)*:
If no initialization
is performed, the object has an indeterminate value[.](#24.1.sentence-2)
— *end note*]
- [(24.2)](#24.2)
Otherwise, the [*new-initializer*](#nt:new-initializer "7.6.2.8New[expr.new]") is interpreted according to
the initialization rules of [[dcl.init]](dcl.init "9.5Initializers") for direct-initialization[.](#24.2.sentence-1)
[25](#25)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L6267)
The invocation of the allocation function is sequenced before
the evaluations of expressions in the [*new-initializer*](#nt:new-initializer "7.6.2.8New[expr.new]")[.](#25.sentence-1)
Initialization of
the allocated object is sequenced before thevalue computation of the[*new-expression*](#nt:new-expression "7.6.2.8New[expr.new]")[.](#25.sentence-2)
[26](#26)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L6277)
If the [*new-expression*](#nt:new-expression "7.6.2.8New[expr.new]") creates an array of objects of class type, the destructor is potentially
invoked ([[class.dtor]](class.dtor "11.4.7Destructors"))[.](#26.sentence-1)
[27](#27)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L6282)
If any part of the object initialization described above[60](#footnote-60 "This can include evaluating a new-initializer and/or calling a constructor.") terminates by throwing an exception and a suitable deallocation function
can be found, the deallocation function is called to free the memory in
which the object was being constructed, after which the exception
continues to propagate in the context of the [*new-expression*](#nt:new-expression "7.6.2.8New[expr.new]")[.](#27.sentence-1)
If no unambiguous matching deallocation function can be found,
propagating the exception does not cause the object's memory to be
freed[.](#27.sentence-2)
[*Note [13](#note-13)*:
This is appropriate when the called allocation function does not
allocate memory; otherwise, it is likely to result in a memory leak[.](#27.sentence-3)
— *end note*]
[28](#28)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L6302)
If the [*new-expression*](#nt:new-expression "7.6.2.8New[expr.new]") does not begin with
a unary :: operator and
the allocated type is a class type T or an array thereof,
a search is performed for the deallocation function's name
in the scope of T[.](#28.sentence-1)
Otherwise, or if nothing is found,
the deallocation function's name is looked up by
searching for it in the global scope[.](#28.sentence-2)
[29](#29)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L6312)
A declaration of a placement deallocation function matches the
declaration of a placement allocation function if it has the same number
of parameters and, after parameter transformations ([[dcl.fct]](dcl.fct "9.3.4.6Functions")), all
parameter types except the first are identical[.](#29.sentence-1)
If
the lookup finds a single matching deallocation function, that function
will be called; otherwise, no deallocation function will be called[.](#29.sentence-2)
If
the lookup finds a usual deallocation
function
and that function,
considered as a placement deallocation function, would have been
selected as a match for the allocation function, the program is
ill-formed[.](#29.sentence-3)
For a non-placement allocation function, the normal deallocation
function lookup is used to find the matching deallocation
function ([[expr.delete]](expr.delete "7.6.2.9Delete"))[.](#29.sentence-4)
In any case,
the matching deallocation function (if any) shall be non-deleted and
accessible from the point where the [*new-expression*](#nt:new-expression "7.6.2.8New[expr.new]") appears[.](#29.sentence-5)
[*Example [7](#example-7)*: struct S {// Placement allocation function:static void* operator new(std::size_t, std::size_t); // Usual (non-placement) deallocation function:static void operator delete(void*, std::size_t);};
S* p = new (0) S; // error: non-placement deallocation function matches// placement allocation function — *end example*]
[30](#30)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L6345)
If a [*new-expression*](#nt:new-expression "7.6.2.8New[expr.new]") calls a deallocation function, it passes
the value returned from the allocation function call as the first
argument of type void*[.](#30.sentence-1)
If a placement deallocation function is
called, it is passed the same additional arguments as were passed to the
placement allocation function, that is, the same arguments as those
specified with the [*new-placement*](#nt:new-placement "7.6.2.8New[expr.new]") syntax[.](#30.sentence-2)
If the implementation is allowed
to introduce a temporary object or make a copy of any argument
as part of the call to the allocation function,
it is unspecified whether the same object is used in the call
to both the allocation and deallocation functions[.](#30.sentence-3)
[59)](#footnote-59)[59)](#footnoteref-59)
If the conversion function
returns a signed integer type, the second standard conversion converts to the
unsigned type std::size_t and thus thwarts any attempt to detect a
negative value afterwards[.](#footnote-59.sentence-1)
[60)](#footnote-60)[60)](#footnoteref-60)
This can
include evaluating a [*new-initializer*](#nt:new-initializer "7.6.2.8New[expr.new]") and/or calling
a constructor[.](#footnote-60.sentence-1)