From Jason Turner

[basic.stc.dynamic]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp3b1klpq8/{from.md → to.md} +123 -113
tmp/tmp3b1klpq8/{from.md → to.md} RENAMED
@@ -1,40 +1,39 @@
1
- ### Dynamic storage duration <a id="basic.stc.dynamic">[[basic.stc.dynamic]]</a>
2
 
3
- Objects can be created dynamically during program execution (
4
- [[intro.execution]]), using *new-expression*s ([[expr.new]]), and
5
- destroyed using *delete-expression*s ([[expr.delete]]). A
6
- C++implementation provides access to, and management of, dynamic storage
7
- via the global *allocation functions* `operator new` and `operator
8
  new[]` and the global *deallocation functions* `operator
9
  delete` and `operator delete[]`.
10
 
11
  [*Note 1*: The non-allocating forms described in
12
  [[new.delete.placement]] do not perform allocation or
13
  deallocation. — *end note*]
14
 
15
  The library provides default definitions for the global allocation and
16
  deallocation functions. Some global allocation and deallocation
17
- functions are replaceable ([[new.delete]]). A C++program shall provide
18
- at most one definition of a replaceable allocation or deallocation
19
  function. Any such function definition replaces the default version
20
- provided in the library ([[replacement.functions]]). The following
21
- allocation and deallocation functions ([[support.dynamic]]) are
22
- implicitly declared in global scope in each translation unit of a
23
- program.
24
 
25
  ``` cpp
26
- void* operator new(std::size_t);
27
- void* operator new(std::size_t, std::align_val_t);
28
 
29
  void operator delete(void*) noexcept;
30
  void operator delete(void*, std::size_t) noexcept;
31
  void operator delete(void*, std::align_val_t) noexcept;
32
  void operator delete(void*, std::size_t, std::align_val_t) noexcept;
33
 
34
- void* operator new[](std::size_t);
35
- void* operator new[](std::size_t, std::align_val_t);
36
 
37
  void operator delete[](void*) noexcept;
38
  void operator delete[](void*, std::size_t) noexcept;
39
  void operator delete[](void*, std::align_val_t) noexcept;
40
  void operator delete[](void*, std::size_t, std::align_val_t) noexcept;
@@ -45,152 +44,165 @@ These implicit declarations introduce only the function names `operator`
45
  `delete[]`.
46
 
47
  [*Note 2*: The implicit declarations do not introduce the names `std`,
48
  `std::size_t`, `std::align_val_t`, or any other names that the library
49
  uses to declare these names. Thus, a *new-expression*,
50
- *delete-expression* or function call that refers to one of these
51
- functions without including the header `<new>` is well-formed. However,
52
- referring to `std` or `std::size_t` or `std::align_val_t` is ill-formed
53
- unless the name has been declared by including the appropriate
54
- header. — *end note*]
55
 
56
  Allocation and/or deallocation functions may also be declared and
57
- defined for any class ([[class.free]]).
58
 
59
- Any allocation and/or deallocation functions defined in a C++program,
60
- including the default versions in the library, shall conform to the
61
- semantics specified in  [[basic.stc.dynamic.allocation]] and 
62
- [[basic.stc.dynamic.deallocation]].
63
 
64
- #### Allocation functions <a id="basic.stc.dynamic.allocation">[[basic.stc.dynamic.allocation]]</a>
65
 
66
  An allocation function shall be a class member function or a global
67
  function; a program is ill-formed if an allocation function is declared
68
  in a namespace scope other than global scope or declared static in
69
  global scope. The return type shall be `void*`. The first parameter
70
- shall have type `std::size_t` ([[support.types]]). The first parameter
71
- shall not have an associated default argument ([[dcl.fct.default]]).
72
- The value of the first parameter shall be interpreted as the requested
73
- size of the allocation. An allocation function can be a function
74
- template. Such a template shall declare its return type and first
75
- parameter as specified above (that is, template parameter types shall
76
- not be used in the return type and first parameter type). Template
77
- allocation functions shall have two or more parameters.
78
 
79
- The allocation function attempts to allocate the requested amount of
80
- storage. If it is successful, it shall return the address of the start
81
- of a block of storage whose length in bytes shall be at least as large
82
- as the requested size. There are no constraints on the contents of the
83
- allocated storage on return from the allocation function. The order,
84
- contiguity, and initial value of storage allocated by successive calls
85
- to an allocation function are unspecified. The pointer returned shall be
86
- suitably aligned so that it can be converted to a pointer to any
87
- suitable complete object type ([[new.delete.single]]) and then used to
88
- access the object or array in the storage allocated (until the storage
89
- is explicitly deallocated by a call to a corresponding deallocation
90
- function). Even if the size of the space requested is zero, the request
91
- can fail. If the request succeeds, the value returned shall be a
92
- non-null pointer value ([[conv.ptr]]) `p0` different from any
93
- previously returned value `p1`, unless that value `p1` was subsequently
94
- passed to an `operator` `delete`. Furthermore, for the library
95
- allocation functions in  [[new.delete.single]] and 
96
- [[new.delete.array]], `p0` shall represent the address of a block of
97
- storage disjoint from the storage for any other object accessible to the
98
- caller. The effect of indirecting through a pointer returned as a
99
- request for zero size is undefined.[^13]
 
 
 
 
 
 
 
100
 
101
  An allocation function that fails to allocate storage can invoke the
102
- currently installed new-handler function ([[new.handler]]), if any.
103
 
104
- [*Note 1*: A program-supplied allocation function can obtain the
105
  address of the currently installed `new_handler` using the
106
- `std::get_new_handler` function ([[set.new.handler]]). — *end note*]
107
 
108
- If an allocation function that has a non-throwing exception
109
- specification ([[except.spec]]) fails to allocate storage, it shall
110
- return a null pointer. Any other allocation function that fails to
111
- allocate storage shall indicate failure only by throwing an exception (
112
- [[except.throw]]) of a type that would match a handler (
113
- [[except.handle]]) of type `std::bad_alloc` ([[bad.alloc]]).
114
 
115
  A global allocation function is only called as the result of a new
116
- expression ([[expr.new]]), or called directly using the function call
117
- syntax ([[expr.call]]), or called indirectly through calls to the
118
- functions in the C++standard library.
 
119
 
120
- [*Note 2*: In particular, a global allocation function is not called to
121
- allocate storage for objects with static storage duration (
122
- [[basic.stc.static]]), for objects or references with thread storage
123
- duration ([[basic.stc.thread]]), for objects of type `std::type_info` (
124
- [[expr.typeid]]), or for an exception object (
125
- [[except.throw]]). — *end note*]
126
 
127
- #### Deallocation functions <a id="basic.stc.dynamic.deallocation">[[basic.stc.dynamic.deallocation]]</a>
128
 
129
  Deallocation functions shall be class member functions or global
130
  functions; a program is ill-formed if deallocation functions are
131
  declared in a namespace scope other than global scope or declared static
132
  in global scope.
133
 
134
- Each deallocation function shall return `void` and its first parameter
135
- shall be `void*`. A deallocation function may have more than one
136
- parameter. A *usual deallocation function* is a deallocation function
137
- that has:
138
 
139
- - exactly one parameter; or
140
- - exactly two parameters, the type of the second being either
141
- `std::align_val_t` or `std::size_t` [^14]; or
142
- - exactly three parameters, the type of the second being `std::size_t`
143
- and the type of the third being `std::align_val_t`.
144
 
145
- A deallocation function may be an instance of a function template.
146
- Neither the first parameter nor the return type shall depend on a
147
- template parameter.
 
 
 
148
 
149
- [*Note 1*: That is, a deallocation function template shall have a first
150
- parameter of type `void*` and a return type of `void` (as specified
151
- above). *end note*]
152
 
153
- A deallocation function template shall have two or more function
154
- parameters. A template instance is never a usual deallocation function,
155
- regardless of its signature.
 
 
 
156
 
157
  If a deallocation function terminates by throwing an exception, the
158
  behavior is undefined. The value of the first argument supplied to a
159
  deallocation function may be a null pointer value; if so, and if the
160
  deallocation function is one supplied in the standard library, the call
161
  has no effect.
162
 
163
  If the argument given to a deallocation function in the standard library
164
- is a pointer that is not the null pointer value ([[conv.ptr]]), the
165
  deallocation function shall deallocate the storage referenced by the
166
  pointer, ending the duration of the region of storage.
167
 
168
- #### Safely-derived pointers <a id="basic.stc.dynamic.safety">[[basic.stc.dynamic.safety]]</a>
169
 
170
  A *traceable pointer object* is
171
 
172
- - an object of an object pointer type ([[basic.compound]]), or
173
  - an object of an integral type that is at least as large as
174
  `std::intptr_t`, or
175
- - a sequence of elements in an array of narrow character type (
176
- [[basic.fundamental]]), where the size and alignment of the sequence
177
  match those of some object pointer type.
178
 
179
- A pointer value is a *safely-derived pointer* to a dynamic object only
180
- if it has an object pointer type and it is one of the following:
 
181
 
182
- - the value returned by a call to the C++standard library implementation
183
- of `::operator new(std::{}size_t)` or
184
- `::operator new(std::size_t, std::align_val_t)` ;[^15]
185
  - the result of taking the address of an object (or one of its
186
  subobjects) designated by an lvalue resulting from indirection through
187
  a safely-derived pointer value;
188
- - the result of well-defined pointer arithmetic ([[expr.add]]) using a
 
 
 
189
  safely-derived pointer value;
190
- - the result of a well-defined pointer conversion ([[conv.ptr]], 
191
- [[expr.cast]]) of a safely-derived pointer value;
192
  - the result of a `reinterpret_cast` of a safely-derived pointer value;
193
  - the result of a `reinterpret_cast` of an integer representation of a
194
  safely-derived pointer value;
195
  - the value of an object whose value was copied from a traceable pointer
196
  object, where at the time of the copy the source object contained a
@@ -216,17 +228,15 @@ An implementation may have *relaxed pointer safety*, in which case the
216
  validity of a pointer value does not depend on whether it is a
217
  safely-derived pointer value. Alternatively, an implementation may have
218
  *strict pointer safety*, in which case a pointer value referring to an
219
  object with dynamic storage duration that is not a safely-derived
220
  pointer value is an invalid pointer value unless the referenced complete
221
- object has previously been declared reachable (
222
- [[util.dynamic.safety]]).
223
 
224
- [*Note 1*: The effect of using an invalid pointer value (including
225
- passing it to a deallocation function) is undefined, see 
226
- [[basic.stc.dynamic.deallocation]]. This is true even if the
227
- unsafely-derived pointer value might compare equal to some
228
- safely-derived pointer value. — *end note*]
229
 
230
  It is *implementation-defined* whether an implementation has relaxed or
231
  strict pointer safety.
232
 
 
1
+ #### Dynamic storage duration <a id="basic.stc.dynamic">[[basic.stc.dynamic]]</a>
2
 
3
+ Objects can be created dynamically during program execution
4
+ [[intro.execution]], using *new-expression*s [[expr.new]], and destroyed
5
+ using *delete-expression*s [[expr.delete]]. A C++ implementation
6
+ provides access to, and management of, dynamic storage via the global
7
+ *allocation functions* `operator new` and `operator
8
  new[]` and the global *deallocation functions* `operator
9
  delete` and `operator delete[]`.
10
 
11
  [*Note 1*: The non-allocating forms described in
12
  [[new.delete.placement]] do not perform allocation or
13
  deallocation. — *end note*]
14
 
15
  The library provides default definitions for the global allocation and
16
  deallocation functions. Some global allocation and deallocation
17
+ functions are replaceable [[new.delete]]. A C++ program shall provide at
18
+ most one definition of a replaceable allocation or deallocation
19
  function. Any such function definition replaces the default version
20
+ provided in the library [[replacement.functions]]. The following
21
+ allocation and deallocation functions [[support.dynamic]] are implicitly
22
+ declared in global scope in each translation unit of a program.
 
23
 
24
  ``` cpp
25
+ [[nodiscard]] void* operator new(std::size_t);
26
+ [[nodiscard]] void* operator new(std::size_t, std::align_val_t);
27
 
28
  void operator delete(void*) noexcept;
29
  void operator delete(void*, std::size_t) noexcept;
30
  void operator delete(void*, std::align_val_t) noexcept;
31
  void operator delete(void*, std::size_t, std::align_val_t) noexcept;
32
 
33
+ [[nodiscard]] void* operator new[](std::size_t);
34
+ [[nodiscard]] void* operator new[](std::size_t, std::align_val_t);
35
 
36
  void operator delete[](void*) noexcept;
37
  void operator delete[](void*, std::size_t) noexcept;
38
  void operator delete[](void*, std::align_val_t) noexcept;
39
  void operator delete[](void*, std::size_t, std::align_val_t) noexcept;
 
44
  `delete[]`.
45
 
46
  [*Note 2*: The implicit declarations do not introduce the names `std`,
47
  `std::size_t`, `std::align_val_t`, or any other names that the library
48
  uses to declare these names. Thus, a *new-expression*,
49
+ *delete-expression*, or function call that refers to one of these
50
+ functions without importing or including the header `<new>` is
51
+ well-formed. However, referring to `std` or `std::size_t` or
52
+ `std::align_val_t` is ill-formed unless the name has been declared by
53
+ importing or including the appropriate header. — *end note*]
54
 
55
  Allocation and/or deallocation functions may also be declared and
56
+ defined for any class [[class.free]].
57
 
58
+ If the behavior of an allocation or deallocation function does not
59
+ satisfy the semantic constraints specified in 
60
+ [[basic.stc.dynamic.allocation]] and 
61
+ [[basic.stc.dynamic.deallocation]], the behavior is undefined.
62
 
63
+ ##### Allocation functions <a id="basic.stc.dynamic.allocation">[[basic.stc.dynamic.allocation]]</a>
64
 
65
  An allocation function shall be a class member function or a global
66
  function; a program is ill-formed if an allocation function is declared
67
  in a namespace scope other than global scope or declared static in
68
  global scope. The return type shall be `void*`. The first parameter
69
+ shall have type `std::size_t` [[support.types]]. The first parameter
70
+ shall not have an associated default argument [[dcl.fct.default]]. The
71
+ value of the first parameter is interpreted as the requested size of the
72
+ allocation. An allocation function can be a function template. Such a
73
+ template shall declare its return type and first parameter as specified
74
+ above (that is, template parameter types shall not be used in the return
75
+ type and first parameter type). Template allocation functions shall have
76
+ two or more parameters.
77
 
78
+ An allocation function attempts to allocate the requested amount of
79
+ storage. If it is successful, it returns the address of the start of a
80
+ block of storage whose length in bytes is at least as large as the
81
+ requested size. The order, contiguity, and initial value of storage
82
+ allocated by successive calls to an allocation function are unspecified.
83
+ Even if the size of the space requested is zero, the request can fail.
84
+ If the request succeeds, the value returned by a replaceable allocation
85
+ function is a non-null pointer value [[basic.compound]] `p0` different
86
+ from any previously returned value `p1`, unless that value `p1` was
87
+ subsequently passed to a replaceable deallocation function. Furthermore,
88
+ for the library allocation functions in  [[new.delete.single]] and 
89
+ [[new.delete.array]], `p0` represents the address of a block of storage
90
+ disjoint from the storage for any other object accessible to the caller.
91
+ The effect of indirecting through a pointer returned from a request for
92
+ zero size is undefined.[^14]
93
+
94
+ For an allocation function other than a reserved placement allocation
95
+ function [[new.delete.placement]], the pointer returned on a successful
96
+ call shall represent the address of storage that is aligned as follows:
97
+
98
+ - If the allocation function takes an argument of type
99
+ `std::align_val_t`, the storage will have the alignment specified by
100
+ the value of this argument.
101
+ - Otherwise, if the allocation function is named `operator new[]`, the
102
+ storage is aligned for any object that does not have new-extended
103
+ alignment [[basic.align]] and is no larger than the requested size.
104
+ - Otherwise, the storage is aligned for any object that does not have
105
+ new-extended alignment and is of the requested size.
106
 
107
  An allocation function that fails to allocate storage can invoke the
108
+ currently installed new-handler function [[new.handler]], if any.
109
 
110
+ [*Note 3*: A program-supplied allocation function can obtain the
111
  address of the currently installed `new_handler` using the
112
+ `std::get_new_handler` function [[get.new.handler]]. — *end note*]
113
 
114
+ An allocation function that has a non-throwing exception specification
115
+ [[except.spec]] indicates failure by returning a null pointer value. Any
116
+ other allocation function never returns a null pointer value and
117
+ indicates failure only by throwing an exception [[except.throw]] of a
118
+ type that would match a handler [[except.handle]] of type
119
+ `std::bad_alloc` [[bad.alloc]].
120
 
121
  A global allocation function is only called as the result of a new
122
+ expression [[expr.new]], or called directly using the function call
123
+ syntax [[expr.call]], or called indirectly to allocate storage for a
124
+ coroutine state [[dcl.fct.def.coroutine]], or called indirectly through
125
+ calls to the functions in the C++ standard library.
126
 
127
+ [*Note 4*: In particular, a global allocation function is not called to
128
+ allocate storage for objects with static storage duration
129
+ [[basic.stc.static]], for objects or references with thread storage
130
+ duration [[basic.stc.thread]], for objects of type `std::type_info`
131
+ [[expr.typeid]], or for an exception object
132
+ [[except.throw]]. — *end note*]
133
 
134
+ ##### Deallocation functions <a id="basic.stc.dynamic.deallocation">[[basic.stc.dynamic.deallocation]]</a>
135
 
136
  Deallocation functions shall be class member functions or global
137
  functions; a program is ill-formed if deallocation functions are
138
  declared in a namespace scope other than global scope or declared static
139
  in global scope.
140
 
141
+ A deallocation function is a *destroying operator delete* if it has at
142
+ least two parameters and its second parameter is of type
143
+ `std::destroying_delete_t`. A destroying operator delete shall be a
144
+ class member function named `operator delete`.
145
 
146
+ [*Note 5*: Array deletion cannot use a destroying operator
147
+ delete. *end note*]
 
 
 
148
 
149
+ Each deallocation function shall return `void`. If the function is a
150
+ destroying operator delete declared in class type `C`, the type of its
151
+ first parameter shall be `C*`; otherwise, the type of its first
152
+ parameter shall be `void*`. A deallocation function may have more than
153
+ one parameter. A *usual deallocation function* is a deallocation
154
+ function whose parameters after the first are
155
 
156
+ - optionally, a parameter of type `std::destroying_delete_t`, then
157
+ - optionally, a parameter of type `std::size_t` [^15], then
158
+ - optionally, a parameter of type `std::align_val_t`.
159
 
160
+ A destroying operator delete shall be a usual deallocation function. A
161
+ deallocation function may be an instance of a function template. Neither
162
+ the first parameter nor the return type shall depend on a template
163
+ parameter. A deallocation function template shall have two or more
164
+ function parameters. A template instance is never a usual deallocation
165
+ function, regardless of its signature.
166
 
167
  If a deallocation function terminates by throwing an exception, the
168
  behavior is undefined. The value of the first argument supplied to a
169
  deallocation function may be a null pointer value; if so, and if the
170
  deallocation function is one supplied in the standard library, the call
171
  has no effect.
172
 
173
  If the argument given to a deallocation function in the standard library
174
+ is a pointer that is not the null pointer value [[basic.compound]], the
175
  deallocation function shall deallocate the storage referenced by the
176
  pointer, ending the duration of the region of storage.
177
 
178
+ ##### Safely-derived pointers <a id="basic.stc.dynamic.safety">[[basic.stc.dynamic.safety]]</a>
179
 
180
  A *traceable pointer object* is
181
 
182
+ - an object of an object pointer type [[basic.compound]], or
183
  - an object of an integral type that is at least as large as
184
  `std::intptr_t`, or
185
+ - a sequence of elements in an array of narrow character type
186
+ [[basic.fundamental]], where the size and alignment of the sequence
187
  match those of some object pointer type.
188
 
189
+ A pointer value is a *safely-derived pointer* to an object with dynamic
190
+ storage duration only if the pointer value has an object pointer type
191
+ and is one of the following:
192
 
193
+ - the value returned by a call to the C++ standard library
194
+ implementation of `::operator new(std::{}size_t)` or
195
+ `::operator new(std::size_t, std::align_val_t)` ;[^16]
196
  - the result of taking the address of an object (or one of its
197
  subobjects) designated by an lvalue resulting from indirection through
198
  a safely-derived pointer value;
199
+ - the result of well-defined pointer arithmetic [[expr.add]] using a
200
+ safely-derived pointer value;
201
+ - the result of a well-defined pointer conversion ([[conv.ptr]],
202
+ [[expr.type.conv]], [[expr.static.cast]], [[expr.cast]]) of a
203
  safely-derived pointer value;
 
 
204
  - the result of a `reinterpret_cast` of a safely-derived pointer value;
205
  - the result of a `reinterpret_cast` of an integer representation of a
206
  safely-derived pointer value;
207
  - the value of an object whose value was copied from a traceable pointer
208
  object, where at the time of the copy the source object contained a
 
228
  validity of a pointer value does not depend on whether it is a
229
  safely-derived pointer value. Alternatively, an implementation may have
230
  *strict pointer safety*, in which case a pointer value referring to an
231
  object with dynamic storage duration that is not a safely-derived
232
  pointer value is an invalid pointer value unless the referenced complete
233
+ object has previously been declared reachable [[util.dynamic.safety]].
 
234
 
235
+ [*Note 6*: The effect of using an invalid pointer value (including
236
+ passing it to a deallocation function) is undefined, see  [[basic.stc]].
237
+ This is true even if the unsafely-derived pointer value might compare
238
+ equal to some safely-derived pointer value. *end note*]
 
239
 
240
  It is *implementation-defined* whether an implementation has relaxed or
241
  strict pointer safety.
242