From Jason Turner

[basic.stc]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpiuvk2gmw/{from.md → to.md} +144 -134
tmp/tmpiuvk2gmw/{from.md → to.md} RENAMED
@@ -1,6 +1,6 @@
1
- ## Storage duration <a id="basic.stc">[[basic.stc]]</a>
2
 
3
  The *storage duration* is the property of an object that defines the
4
  minimum potential lifetime of the storage containing the object. The
5
  storage duration is determined by the construct used to create the
6
  object and is one of the following:
@@ -9,36 +9,35 @@ object and is one of the following:
9
  - thread storage duration
10
  - automatic storage duration
11
  - dynamic storage duration
12
 
13
  Static, thread, and automatic storage durations are associated with
14
- objects introduced by declarations ([[basic.def]]) and implicitly
15
- created by the implementation ([[class.temporary]]). The dynamic
16
- storage duration is associated with objects created by a
17
- *new-expression* ([[expr.new]]).
18
 
19
  The storage duration categories apply to references as well.
20
 
21
  When the end of the duration of a region of storage is reached, the
22
  values of all pointers representing the address of any part of that
23
- region of storage become invalid pointer values ([[basic.compound]]).
24
  Indirection through an invalid pointer value and passing an invalid
25
  pointer value to a deallocation function have undefined behavior. Any
26
  other use of an invalid pointer value has *implementation-defined*
27
- behavior.[^12]
28
 
29
- ### Static storage duration <a id="basic.stc.static">[[basic.stc.static]]</a>
30
 
31
  All variables which do not have dynamic storage duration, do not have
32
  thread storage duration, and are not local have *static storage
33
- duration*. The storage for these entities shall last for the duration of
34
- the program ([[basic.start.static]], [[basic.start.term]]).
35
 
36
  If a variable with static storage duration has initialization or a
37
  destructor with side effects, it shall not be eliminated even if it
38
  appears to be unused, except that a class object or its copy/move may be
39
- eliminated as specified in  [[class.copy]].
40
 
41
  The keyword `static` can be used to declare a local variable with static
42
  storage duration.
43
 
44
  [*Note 1*: [[stmt.dcl]] describes the initialization of local `static`
@@ -46,23 +45,24 @@ variables; [[basic.start.term]] describes the destruction of local
46
  `static` variables. — *end note*]
47
 
48
  The keyword `static` applied to a class data member in a class
49
  definition gives the data member static storage duration.
50
 
51
- ### Thread storage duration <a id="basic.stc.thread">[[basic.stc.thread]]</a>
52
 
53
- All variables declared with the `thread_local` keyword have *thread
54
- storage duration*. The storage for these entities shall last for the
55
  duration of the thread in which they are created. There is a distinct
56
  object or reference per thread, and use of the declared name refers to
57
  the entity associated with the current thread.
58
 
59
- A variable with thread storage duration shall be initialized before its
60
- first odr-use ([[basic.def.odr]]) and, if constructed, shall be
61
- destroyed on thread exit.
 
62
 
63
- ### Automatic storage duration <a id="basic.stc.auto">[[basic.stc.auto]]</a>
64
 
65
  Block-scope variables not explicitly declared `static`, `thread_local`,
66
  or `extern` have *automatic storage duration*. The storage for these
67
  entities lasts until the block in which they are created exits.
68
 
@@ -71,47 +71,46 @@ in  [[stmt.dcl]]. — *end note*]
71
 
72
  If a variable with automatic storage duration has initialization or a
73
  destructor with side effects, an implementation shall not destroy it
74
  before the end of its block nor eliminate it as an optimization, even if
75
  it appears to be unused, except that a class object or its copy/move may
76
- be eliminated as specified in  [[class.copy]].
77
 
78
- ### Dynamic storage duration <a id="basic.stc.dynamic">[[basic.stc.dynamic]]</a>
79
 
80
- Objects can be created dynamically during program execution (
81
- [[intro.execution]]), using *new-expression*s ([[expr.new]]), and
82
- destroyed using *delete-expression*s ([[expr.delete]]). A
83
- C++implementation provides access to, and management of, dynamic storage
84
- via the global *allocation functions* `operator new` and `operator
85
  new[]` and the global *deallocation functions* `operator
86
  delete` and `operator delete[]`.
87
 
88
  [*Note 1*: The non-allocating forms described in
89
  [[new.delete.placement]] do not perform allocation or
90
  deallocation. — *end note*]
91
 
92
  The library provides default definitions for the global allocation and
93
  deallocation functions. Some global allocation and deallocation
94
- functions are replaceable ([[new.delete]]). A C++program shall provide
95
- at most one definition of a replaceable allocation or deallocation
96
  function. Any such function definition replaces the default version
97
- provided in the library ([[replacement.functions]]). The following
98
- allocation and deallocation functions ([[support.dynamic]]) are
99
- implicitly declared in global scope in each translation unit of a
100
- program.
101
 
102
  ``` cpp
103
- void* operator new(std::size_t);
104
- void* operator new(std::size_t, std::align_val_t);
105
 
106
  void operator delete(void*) noexcept;
107
  void operator delete(void*, std::size_t) noexcept;
108
  void operator delete(void*, std::align_val_t) noexcept;
109
  void operator delete(void*, std::size_t, std::align_val_t) noexcept;
110
 
111
- void* operator new[](std::size_t);
112
- void* operator new[](std::size_t, std::align_val_t);
113
 
114
  void operator delete[](void*) noexcept;
115
  void operator delete[](void*, std::size_t) noexcept;
116
  void operator delete[](void*, std::align_val_t) noexcept;
117
  void operator delete[](void*, std::size_t, std::align_val_t) noexcept;
@@ -122,152 +121,165 @@ These implicit declarations introduce only the function names `operator`
122
  `delete[]`.
123
 
124
  [*Note 2*: The implicit declarations do not introduce the names `std`,
125
  `std::size_t`, `std::align_val_t`, or any other names that the library
126
  uses to declare these names. Thus, a *new-expression*,
127
- *delete-expression* or function call that refers to one of these
128
- functions without including the header `<new>` is well-formed. However,
129
- referring to `std` or `std::size_t` or `std::align_val_t` is ill-formed
130
- unless the name has been declared by including the appropriate
131
- header. — *end note*]
132
 
133
  Allocation and/or deallocation functions may also be declared and
134
- defined for any class ([[class.free]]).
135
 
136
- Any allocation and/or deallocation functions defined in a C++program,
137
- including the default versions in the library, shall conform to the
138
- semantics specified in  [[basic.stc.dynamic.allocation]] and 
139
- [[basic.stc.dynamic.deallocation]].
140
 
141
- #### Allocation functions <a id="basic.stc.dynamic.allocation">[[basic.stc.dynamic.allocation]]</a>
142
 
143
  An allocation function shall be a class member function or a global
144
  function; a program is ill-formed if an allocation function is declared
145
  in a namespace scope other than global scope or declared static in
146
  global scope. The return type shall be `void*`. The first parameter
147
- shall have type `std::size_t` ([[support.types]]). The first parameter
148
- shall not have an associated default argument ([[dcl.fct.default]]).
149
- The value of the first parameter shall be interpreted as the requested
150
- size of the allocation. An allocation function can be a function
151
- template. Such a template shall declare its return type and first
152
- parameter as specified above (that is, template parameter types shall
153
- not be used in the return type and first parameter type). Template
154
- allocation functions shall have two or more parameters.
155
 
156
- The allocation function attempts to allocate the requested amount of
157
- storage. If it is successful, it shall return the address of the start
158
- of a block of storage whose length in bytes shall be at least as large
159
- as the requested size. There are no constraints on the contents of the
160
- allocated storage on return from the allocation function. The order,
161
- contiguity, and initial value of storage allocated by successive calls
162
- to an allocation function are unspecified. The pointer returned shall be
163
- suitably aligned so that it can be converted to a pointer to any
164
- suitable complete object type ([[new.delete.single]]) and then used to
165
- access the object or array in the storage allocated (until the storage
166
- is explicitly deallocated by a call to a corresponding deallocation
167
- function). Even if the size of the space requested is zero, the request
168
- can fail. If the request succeeds, the value returned shall be a
169
- non-null pointer value ([[conv.ptr]]) `p0` different from any
170
- previously returned value `p1`, unless that value `p1` was subsequently
171
- passed to an `operator` `delete`. Furthermore, for the library
172
- allocation functions in  [[new.delete.single]] and 
173
- [[new.delete.array]], `p0` shall represent the address of a block of
174
- storage disjoint from the storage for any other object accessible to the
175
- caller. The effect of indirecting through a pointer returned as a
176
- request for zero size is undefined.[^13]
 
 
 
 
 
 
 
177
 
178
  An allocation function that fails to allocate storage can invoke the
179
- currently installed new-handler function ([[new.handler]]), if any.
180
 
181
- [*Note 1*: A program-supplied allocation function can obtain the
182
  address of the currently installed `new_handler` using the
183
- `std::get_new_handler` function ([[set.new.handler]]). — *end note*]
184
 
185
- If an allocation function that has a non-throwing exception
186
- specification ([[except.spec]]) fails to allocate storage, it shall
187
- return a null pointer. Any other allocation function that fails to
188
- allocate storage shall indicate failure only by throwing an exception (
189
- [[except.throw]]) of a type that would match a handler (
190
- [[except.handle]]) of type `std::bad_alloc` ([[bad.alloc]]).
191
 
192
  A global allocation function is only called as the result of a new
193
- expression ([[expr.new]]), or called directly using the function call
194
- syntax ([[expr.call]]), or called indirectly through calls to the
195
- functions in the C++standard library.
 
196
 
197
- [*Note 2*: In particular, a global allocation function is not called to
198
- allocate storage for objects with static storage duration (
199
- [[basic.stc.static]]), for objects or references with thread storage
200
- duration ([[basic.stc.thread]]), for objects of type `std::type_info` (
201
- [[expr.typeid]]), or for an exception object (
202
- [[except.throw]]). — *end note*]
203
 
204
- #### Deallocation functions <a id="basic.stc.dynamic.deallocation">[[basic.stc.dynamic.deallocation]]</a>
205
 
206
  Deallocation functions shall be class member functions or global
207
  functions; a program is ill-formed if deallocation functions are
208
  declared in a namespace scope other than global scope or declared static
209
  in global scope.
210
 
211
- Each deallocation function shall return `void` and its first parameter
212
- shall be `void*`. A deallocation function may have more than one
213
- parameter. A *usual deallocation function* is a deallocation function
214
- that has:
215
 
216
- - exactly one parameter; or
217
- - exactly two parameters, the type of the second being either
218
- `std::align_val_t` or `std::size_t` [^14]; or
219
- - exactly three parameters, the type of the second being `std::size_t`
220
- and the type of the third being `std::align_val_t`.
221
 
222
- A deallocation function may be an instance of a function template.
223
- Neither the first parameter nor the return type shall depend on a
224
- template parameter.
 
 
 
225
 
226
- [*Note 1*: That is, a deallocation function template shall have a first
227
- parameter of type `void*` and a return type of `void` (as specified
228
- above). *end note*]
229
 
230
- A deallocation function template shall have two or more function
231
- parameters. A template instance is never a usual deallocation function,
232
- regardless of its signature.
 
 
 
233
 
234
  If a deallocation function terminates by throwing an exception, the
235
  behavior is undefined. The value of the first argument supplied to a
236
  deallocation function may be a null pointer value; if so, and if the
237
  deallocation function is one supplied in the standard library, the call
238
  has no effect.
239
 
240
  If the argument given to a deallocation function in the standard library
241
- is a pointer that is not the null pointer value ([[conv.ptr]]), the
242
  deallocation function shall deallocate the storage referenced by the
243
  pointer, ending the duration of the region of storage.
244
 
245
- #### Safely-derived pointers <a id="basic.stc.dynamic.safety">[[basic.stc.dynamic.safety]]</a>
246
 
247
  A *traceable pointer object* is
248
 
249
- - an object of an object pointer type ([[basic.compound]]), or
250
  - an object of an integral type that is at least as large as
251
  `std::intptr_t`, or
252
- - a sequence of elements in an array of narrow character type (
253
- [[basic.fundamental]]), where the size and alignment of the sequence
254
  match those of some object pointer type.
255
 
256
- A pointer value is a *safely-derived pointer* to a dynamic object only
257
- if it has an object pointer type and it is one of the following:
 
258
 
259
- - the value returned by a call to the C++standard library implementation
260
- of `::operator new(std::{}size_t)` or
261
- `::operator new(std::size_t, std::align_val_t)` ;[^15]
262
  - the result of taking the address of an object (or one of its
263
  subobjects) designated by an lvalue resulting from indirection through
264
  a safely-derived pointer value;
265
- - the result of well-defined pointer arithmetic ([[expr.add]]) using a
 
 
 
266
  safely-derived pointer value;
267
- - the result of a well-defined pointer conversion ([[conv.ptr]], 
268
- [[expr.cast]]) of a safely-derived pointer value;
269
  - the result of a `reinterpret_cast` of a safely-derived pointer value;
270
  - the result of a `reinterpret_cast` of an integer representation of a
271
  safely-derived pointer value;
272
  - the value of an object whose value was copied from a traceable pointer
273
  object, where at the time of the copy the source object contained a
@@ -293,22 +305,20 @@ An implementation may have *relaxed pointer safety*, in which case the
293
  validity of a pointer value does not depend on whether it is a
294
  safely-derived pointer value. Alternatively, an implementation may have
295
  *strict pointer safety*, in which case a pointer value referring to an
296
  object with dynamic storage duration that is not a safely-derived
297
  pointer value is an invalid pointer value unless the referenced complete
298
- object has previously been declared reachable (
299
- [[util.dynamic.safety]]).
300
 
301
- [*Note 1*: The effect of using an invalid pointer value (including
302
- passing it to a deallocation function) is undefined, see 
303
- [[basic.stc.dynamic.deallocation]]. This is true even if the
304
- unsafely-derived pointer value might compare equal to some
305
- safely-derived pointer value. — *end note*]
306
 
307
  It is *implementation-defined* whether an implementation has relaxed or
308
  strict pointer safety.
309
 
310
- ### Duration of subobjects <a id="basic.stc.inherit">[[basic.stc.inherit]]</a>
311
 
312
  The storage duration of subobjects and reference members is that of
313
- their complete object ([[intro.object]]).
314
 
 
1
+ ### Storage duration <a id="basic.stc">[[basic.stc]]</a>
2
 
3
  The *storage duration* is the property of an object that defines the
4
  minimum potential lifetime of the storage containing the object. The
5
  storage duration is determined by the construct used to create the
6
  object and is one of the following:
 
9
  - thread storage duration
10
  - automatic storage duration
11
  - dynamic storage duration
12
 
13
  Static, thread, and automatic storage durations are associated with
14
+ objects introduced by declarations [[basic.def]] and implicitly created
15
+ by the implementation [[class.temporary]]. The dynamic storage duration
16
+ is associated with objects created by a *new-expression* [[expr.new]].
 
17
 
18
  The storage duration categories apply to references as well.
19
 
20
  When the end of the duration of a region of storage is reached, the
21
  values of all pointers representing the address of any part of that
22
+ region of storage become invalid pointer values [[basic.compound]].
23
  Indirection through an invalid pointer value and passing an invalid
24
  pointer value to a deallocation function have undefined behavior. Any
25
  other use of an invalid pointer value has *implementation-defined*
26
+ behavior.[^13]
27
 
28
+ #### Static storage duration <a id="basic.stc.static">[[basic.stc.static]]</a>
29
 
30
  All variables which do not have dynamic storage duration, do not have
31
  thread storage duration, and are not local have *static storage
32
+ duration*. The storage for these entities lasts for the duration of the
33
+ program ([[basic.start.static]], [[basic.start.term]]).
34
 
35
  If a variable with static storage duration has initialization or a
36
  destructor with side effects, it shall not be eliminated even if it
37
  appears to be unused, except that a class object or its copy/move may be
38
+ eliminated as specified in  [[class.copy.elision]].
39
 
40
  The keyword `static` can be used to declare a local variable with static
41
  storage duration.
42
 
43
  [*Note 1*: [[stmt.dcl]] describes the initialization of local `static`
 
45
  `static` variables. — *end note*]
46
 
47
  The keyword `static` applied to a class data member in a class
48
  definition gives the data member static storage duration.
49
 
50
+ #### Thread storage duration <a id="basic.stc.thread">[[basic.stc.thread]]</a>
51
 
52
+ All variables declared with the `thread_local` keyword have
53
+ *thread storage duration*. The storage for these entities lasts for the
54
  duration of the thread in which they are created. There is a distinct
55
  object or reference per thread, and use of the declared name refers to
56
  the entity associated with the current thread.
57
 
58
+ [*Note 1*: A variable with thread storage duration is initialized as
59
+ specified in  [[basic.start.static]], [[basic.start.dynamic]], and
60
+ [[stmt.dcl]] and, if constructed, is destroyed on thread exit
61
+ [[basic.start.term]]. — *end note*]
62
 
63
+ #### Automatic storage duration <a id="basic.stc.auto">[[basic.stc.auto]]</a>
64
 
65
  Block-scope variables not explicitly declared `static`, `thread_local`,
66
  or `extern` have *automatic storage duration*. The storage for these
67
  entities lasts until the block in which they are created exits.
68
 
 
71
 
72
  If a variable with automatic storage duration has initialization or a
73
  destructor with side effects, an implementation shall not destroy it
74
  before the end of its block nor eliminate it as an optimization, even if
75
  it appears to be unused, except that a class object or its copy/move may
76
+ be eliminated as specified in  [[class.copy.elision]].
77
 
78
+ #### Dynamic storage duration <a id="basic.stc.dynamic">[[basic.stc.dynamic]]</a>
79
 
80
+ Objects can be created dynamically during program execution
81
+ [[intro.execution]], using *new-expression*s [[expr.new]], and destroyed
82
+ using *delete-expression*s [[expr.delete]]. A C++ implementation
83
+ provides access to, and management of, dynamic storage via the global
84
+ *allocation functions* `operator new` and `operator
85
  new[]` and the global *deallocation functions* `operator
86
  delete` and `operator delete[]`.
87
 
88
  [*Note 1*: The non-allocating forms described in
89
  [[new.delete.placement]] do not perform allocation or
90
  deallocation. — *end note*]
91
 
92
  The library provides default definitions for the global allocation and
93
  deallocation functions. Some global allocation and deallocation
94
+ functions are replaceable [[new.delete]]. A C++ program shall provide at
95
+ most one definition of a replaceable allocation or deallocation
96
  function. Any such function definition replaces the default version
97
+ provided in the library [[replacement.functions]]. The following
98
+ allocation and deallocation functions [[support.dynamic]] are implicitly
99
+ declared in global scope in each translation unit of a program.
 
100
 
101
  ``` cpp
102
+ [[nodiscard]] void* operator new(std::size_t);
103
+ [[nodiscard]] void* operator new(std::size_t, std::align_val_t);
104
 
105
  void operator delete(void*) noexcept;
106
  void operator delete(void*, std::size_t) noexcept;
107
  void operator delete(void*, std::align_val_t) noexcept;
108
  void operator delete(void*, std::size_t, std::align_val_t) noexcept;
109
 
110
+ [[nodiscard]] void* operator new[](std::size_t);
111
+ [[nodiscard]] void* operator new[](std::size_t, std::align_val_t);
112
 
113
  void operator delete[](void*) noexcept;
114
  void operator delete[](void*, std::size_t) noexcept;
115
  void operator delete[](void*, std::align_val_t) noexcept;
116
  void operator delete[](void*, std::size_t, std::align_val_t) noexcept;
 
121
  `delete[]`.
122
 
123
  [*Note 2*: The implicit declarations do not introduce the names `std`,
124
  `std::size_t`, `std::align_val_t`, or any other names that the library
125
  uses to declare these names. Thus, a *new-expression*,
126
+ *delete-expression*, or function call that refers to one of these
127
+ functions without importing or including the header `<new>` is
128
+ well-formed. However, referring to `std` or `std::size_t` or
129
+ `std::align_val_t` is ill-formed unless the name has been declared by
130
+ importing or including the appropriate header. — *end note*]
131
 
132
  Allocation and/or deallocation functions may also be declared and
133
+ defined for any class [[class.free]].
134
 
135
+ If the behavior of an allocation or deallocation function does not
136
+ satisfy the semantic constraints specified in 
137
+ [[basic.stc.dynamic.allocation]] and 
138
+ [[basic.stc.dynamic.deallocation]], the behavior is undefined.
139
 
140
+ ##### Allocation functions <a id="basic.stc.dynamic.allocation">[[basic.stc.dynamic.allocation]]</a>
141
 
142
  An allocation function shall be a class member function or a global
143
  function; a program is ill-formed if an allocation function is declared
144
  in a namespace scope other than global scope or declared static in
145
  global scope. The return type shall be `void*`. The first parameter
146
+ shall have type `std::size_t` [[support.types]]. The first parameter
147
+ shall not have an associated default argument [[dcl.fct.default]]. The
148
+ value of the first parameter is interpreted as the requested size of the
149
+ allocation. An allocation function can be a function template. Such a
150
+ template shall declare its return type and first parameter as specified
151
+ above (that is, template parameter types shall not be used in the return
152
+ type and first parameter type). Template allocation functions shall have
153
+ two or more parameters.
154
 
155
+ An allocation function attempts to allocate the requested amount of
156
+ storage. If it is successful, it returns the address of the start of a
157
+ block of storage whose length in bytes is at least as large as the
158
+ requested size. The order, contiguity, and initial value of storage
159
+ allocated by successive calls to an allocation function are unspecified.
160
+ Even if the size of the space requested is zero, the request can fail.
161
+ If the request succeeds, the value returned by a replaceable allocation
162
+ function is a non-null pointer value [[basic.compound]] `p0` different
163
+ from any previously returned value `p1`, unless that value `p1` was
164
+ subsequently passed to a replaceable deallocation function. Furthermore,
165
+ for the library allocation functions in  [[new.delete.single]] and 
166
+ [[new.delete.array]], `p0` represents the address of a block of storage
167
+ disjoint from the storage for any other object accessible to the caller.
168
+ The effect of indirecting through a pointer returned from a request for
169
+ zero size is undefined.[^14]
170
+
171
+ For an allocation function other than a reserved placement allocation
172
+ function [[new.delete.placement]], the pointer returned on a successful
173
+ call shall represent the address of storage that is aligned as follows:
174
+
175
+ - If the allocation function takes an argument of type
176
+ `std::align_val_t`, the storage will have the alignment specified by
177
+ the value of this argument.
178
+ - Otherwise, if the allocation function is named `operator new[]`, the
179
+ storage is aligned for any object that does not have new-extended
180
+ alignment [[basic.align]] and is no larger than the requested size.
181
+ - Otherwise, the storage is aligned for any object that does not have
182
+ new-extended alignment and is of the requested size.
183
 
184
  An allocation function that fails to allocate storage can invoke the
185
+ currently installed new-handler function [[new.handler]], if any.
186
 
187
+ [*Note 3*: A program-supplied allocation function can obtain the
188
  address of the currently installed `new_handler` using the
189
+ `std::get_new_handler` function [[get.new.handler]]. — *end note*]
190
 
191
+ An allocation function that has a non-throwing exception specification
192
+ [[except.spec]] indicates failure by returning a null pointer value. Any
193
+ other allocation function never returns a null pointer value and
194
+ indicates failure only by throwing an exception [[except.throw]] of a
195
+ type that would match a handler [[except.handle]] of type
196
+ `std::bad_alloc` [[bad.alloc]].
197
 
198
  A global allocation function is only called as the result of a new
199
+ expression [[expr.new]], or called directly using the function call
200
+ syntax [[expr.call]], or called indirectly to allocate storage for a
201
+ coroutine state [[dcl.fct.def.coroutine]], or called indirectly through
202
+ calls to the functions in the C++ standard library.
203
 
204
+ [*Note 4*: In particular, a global allocation function is not called to
205
+ allocate storage for objects with static storage duration
206
+ [[basic.stc.static]], for objects or references with thread storage
207
+ duration [[basic.stc.thread]], for objects of type `std::type_info`
208
+ [[expr.typeid]], or for an exception object
209
+ [[except.throw]]. — *end note*]
210
 
211
+ ##### Deallocation functions <a id="basic.stc.dynamic.deallocation">[[basic.stc.dynamic.deallocation]]</a>
212
 
213
  Deallocation functions shall be class member functions or global
214
  functions; a program is ill-formed if deallocation functions are
215
  declared in a namespace scope other than global scope or declared static
216
  in global scope.
217
 
218
+ A deallocation function is a *destroying operator delete* if it has at
219
+ least two parameters and its second parameter is of type
220
+ `std::destroying_delete_t`. A destroying operator delete shall be a
221
+ class member function named `operator delete`.
222
 
223
+ [*Note 5*: Array deletion cannot use a destroying operator
224
+ delete. *end note*]
 
 
 
225
 
226
+ Each deallocation function shall return `void`. If the function is a
227
+ destroying operator delete declared in class type `C`, the type of its
228
+ first parameter shall be `C*`; otherwise, the type of its first
229
+ parameter shall be `void*`. A deallocation function may have more than
230
+ one parameter. A *usual deallocation function* is a deallocation
231
+ function whose parameters after the first are
232
 
233
+ - optionally, a parameter of type `std::destroying_delete_t`, then
234
+ - optionally, a parameter of type `std::size_t` [^15], then
235
+ - optionally, a parameter of type `std::align_val_t`.
236
 
237
+ A destroying operator delete shall be a usual deallocation function. A
238
+ deallocation function may be an instance of a function template. Neither
239
+ the first parameter nor the return type shall depend on a template
240
+ parameter. A deallocation function template shall have two or more
241
+ function parameters. A template instance is never a usual deallocation
242
+ function, regardless of its signature.
243
 
244
  If a deallocation function terminates by throwing an exception, the
245
  behavior is undefined. The value of the first argument supplied to a
246
  deallocation function may be a null pointer value; if so, and if the
247
  deallocation function is one supplied in the standard library, the call
248
  has no effect.
249
 
250
  If the argument given to a deallocation function in the standard library
251
+ is a pointer that is not the null pointer value [[basic.compound]], the
252
  deallocation function shall deallocate the storage referenced by the
253
  pointer, ending the duration of the region of storage.
254
 
255
+ ##### Safely-derived pointers <a id="basic.stc.dynamic.safety">[[basic.stc.dynamic.safety]]</a>
256
 
257
  A *traceable pointer object* is
258
 
259
+ - an object of an object pointer type [[basic.compound]], or
260
  - an object of an integral type that is at least as large as
261
  `std::intptr_t`, or
262
+ - a sequence of elements in an array of narrow character type
263
+ [[basic.fundamental]], where the size and alignment of the sequence
264
  match those of some object pointer type.
265
 
266
+ A pointer value is a *safely-derived pointer* to an object with dynamic
267
+ storage duration only if the pointer value has an object pointer type
268
+ and is one of the following:
269
 
270
+ - the value returned by a call to the C++ standard library
271
+ implementation of `::operator new(std::{}size_t)` or
272
+ `::operator new(std::size_t, std::align_val_t)` ;[^16]
273
  - the result of taking the address of an object (or one of its
274
  subobjects) designated by an lvalue resulting from indirection through
275
  a safely-derived pointer value;
276
+ - the result of well-defined pointer arithmetic [[expr.add]] using a
277
+ safely-derived pointer value;
278
+ - the result of a well-defined pointer conversion ([[conv.ptr]],
279
+ [[expr.type.conv]], [[expr.static.cast]], [[expr.cast]]) of a
280
  safely-derived pointer value;
 
 
281
  - the result of a `reinterpret_cast` of a safely-derived pointer value;
282
  - the result of a `reinterpret_cast` of an integer representation of a
283
  safely-derived pointer value;
284
  - the value of an object whose value was copied from a traceable pointer
285
  object, where at the time of the copy the source object contained a
 
305
  validity of a pointer value does not depend on whether it is a
306
  safely-derived pointer value. Alternatively, an implementation may have
307
  *strict pointer safety*, in which case a pointer value referring to an
308
  object with dynamic storage duration that is not a safely-derived
309
  pointer value is an invalid pointer value unless the referenced complete
310
+ object has previously been declared reachable [[util.dynamic.safety]].
 
311
 
312
+ [*Note 6*: The effect of using an invalid pointer value (including
313
+ passing it to a deallocation function) is undefined, see  [[basic.stc]].
314
+ This is true even if the unsafely-derived pointer value might compare
315
+ equal to some safely-derived pointer value. *end note*]
 
316
 
317
  It is *implementation-defined* whether an implementation has relaxed or
318
  strict pointer safety.
319
 
320
+ #### Duration of subobjects <a id="basic.stc.inherit">[[basic.stc.inherit]]</a>
321
 
322
  The storage duration of subobjects and reference members is that of
323
+ their complete object [[intro.object]].
324