From Jason Turner

[support.dynamic]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpfu8kst0o/{from.md → to.md} +342 -181
tmp/tmpfu8kst0o/{from.md → to.md} RENAMED
@@ -2,34 +2,54 @@
2
 
3
  The header `<new>` defines several functions that manage the allocation
4
  of dynamic storage in a program. It also defines components for
5
  reporting storage management errors.
6
 
 
 
7
  ``` cpp
8
  namespace std {
9
  class bad_alloc;
10
  class bad_array_new_length;
11
- struct nothrow_t {};
 
12
  extern const nothrow_t nothrow;
13
- typedef void (*new_handler)();
14
  new_handler get_new_handler() noexcept;
15
  new_handler set_new_handler(new_handler new_p) noexcept;
 
 
 
 
 
 
 
16
  }
17
 
18
  void* operator new(std::size_t size);
 
19
  void* operator new(std::size_t size, const std::nothrow_t&) noexcept;
 
 
20
  void operator delete(void* ptr) noexcept;
21
- void operator delete(void* ptr, const std::nothrow_t&) noexcept;
22
  void operator delete(void* ptr, std::size_t size) noexcept;
23
- void operator delete(void* ptr, std::size_t size,
 
 
 
24
  const std::nothrow_t&) noexcept;
25
  void* operator new[](std::size_t size);
 
26
  void* operator new[](std::size_t size, const std::nothrow_t&) noexcept;
 
 
27
  void operator delete[](void* ptr) noexcept;
28
- void operator delete[](void* ptr, const std::nothrow_t&) noexcept;
29
  void operator delete[](void* ptr, std::size_t size) noexcept;
30
- void operator delete[](void* ptr, std::size_t size,
 
 
 
31
  const std::nothrow_t&) noexcept;
32
 
33
  void* operator new (std::size_t size, void* ptr) noexcept;
34
  void* operator new[](std::size_t size, void* ptr) noexcept;
35
  void operator delete (void* ptr, void*) noexcept;
@@ -39,38 +59,46 @@ void operator delete[](void* ptr, void*) noexcept;
39
    [[intro.memory]], [[basic.stc.dynamic]], [[expr.new]],
40
  [[expr.delete]], [[class.free]], [[memory]].
41
 
42
  ### Storage allocation and deallocation <a id="new.delete">[[new.delete]]</a>
43
 
44
- Except where otherwise specified, the provisions of (
45
- [[basic.stc.dynamic]]) apply to the library versions of `operator new`
46
  and `operator
47
- delete`.
 
48
 
49
  #### Single-object forms <a id="new.delete.single">[[new.delete.single]]</a>
50
 
51
  ``` cpp
52
  void* operator new(std::size_t size);
 
53
  ```
54
 
55
- *Effects:* The *allocation function* ([[basic.stc.dynamic.allocation]])
56
  called by a *new-expression* ([[expr.new]]) to allocate `size` bytes of
57
- storage suitably aligned to represent any object of that size.
 
 
 
 
58
 
59
- *Replaceable:* a C++program may define a function with this function
60
- signature that displaces the default version defined by the C++standard
61
- library.
62
 
63
  *Required behavior:* Return a non-null pointer to suitably aligned
64
  storage ([[basic.stc.dynamic]]), or else throw a `bad_alloc` exception.
65
- This requirement is binding on a replacement version of this function.
 
66
 
67
  *Default behavior:*
68
 
69
  - Executes a loop: Within the loop, the function first attempts to
70
  allocate the requested storage. Whether the attempt involves a call to
71
- the Standard C library function `malloc` is unspecified.
 
72
  - Returns a pointer to the allocated storage if the attempt is
73
  successful. Otherwise, if the current
74
  `new_handler` ([[get.new.handler]]) is a null pointer value, throws
75
  `bad_alloc`.
76
  - Otherwise, the function calls the current `new_handler`
@@ -79,277 +107,308 @@ This requirement is binding on a replacement version of this function.
79
  - The loop terminates when an attempt to allocate the requested storage
80
  is successful or when a called `new_handler` function does not return.
81
 
82
  ``` cpp
83
  void* operator new(std::size_t size, const std::nothrow_t&) noexcept;
 
84
  ```
85
 
86
- *Effects:* Same as above, except that it is called by a placement
87
  version of a *new-expression* when a C++program prefers a null pointer
88
  result as an error indication, instead of a `bad_alloc` exception.
89
 
90
- *Replaceable:* a C++program may define a function with this function
91
- signature that displaces the default version defined by the C++standard
92
- library.
93
 
94
  *Required behavior:* Return a non-null pointer to suitably aligned
95
- storage ([[basic.stc.dynamic]]), or else return a null pointer. This
96
- nothrow version of `operator new` returns a pointer obtained as if
97
- acquired from the (possibly replaced) ordinary version. This requirement
98
- is binding on a replacement version of this function.
 
99
 
100
- *Default behavior:* Calls `operator new(size)`. If the call returns
 
101
  normally, returns the result of that call. Otherwise, returns a null
102
  pointer.
103
 
 
 
104
  ``` cpp
105
  T* p1 = new T; // throws bad_alloc if it fails
106
  T* p2 = new(nothrow) T; // returns nullptr if it fails
107
  ```
108
 
 
 
109
  ``` cpp
110
  void operator delete(void* ptr) noexcept;
111
  void operator delete(void* ptr, std::size_t size) noexcept;
 
 
112
  ```
113
 
114
- *Effects:* The *deallocation
115
- function* ([[basic.stc.dynamic.deallocation]]) called by a
116
  *delete-expression* to render the value of `ptr` invalid.
117
 
118
- *Replaceable:* a C++program may define a function with signature
119
- `void operator delete(void* ptr) noexcept` that displaces the default
120
- version defined by the C++standard library. If this function (without
121
- `size` parameter) is defined, the program should also define
122
- `void operator delete(void* ptr, std::size_t size) noexcept`. If this
123
- function with `size` parameter is defined, the program shall also define
124
- the version without the `size` parameter. The default behavior below may
125
- change in the future, which will require replacing both deallocation
126
- functions when replacing the allocation function.
127
 
128
- *Requires:* *ptr* shall be a null pointer or its value shall be a value
129
- returned by an earlier call to the (possibly replaced)
130
- `operator new(std::size_t)` or
131
- `operator new(std::size_t,const std::nothrow_t&)` which has not been
132
- invalidated by an intervening call to `operator delete(void*)`.
 
 
 
 
 
 
 
 
 
133
 
134
  *Requires:* If an implementation has strict pointer
135
  safety ([[basic.stc.dynamic.safety]]) then `ptr` shall be a
136
  safely-derived pointer.
137
 
138
- *Requires:* If present, the `std::size_t size` argument shall equal the
139
- size argument passed to the allocation function that returned `ptr`.
 
 
 
 
140
 
141
- *Required behavior:* Calls to
142
- `operator delete(void* ptr, std::size_t size)` may be changed to calls
143
- to `operator delete(void* ptr)` without affecting memory allocation. A
144
- conforming implementation is for
 
 
145
  `operator delete(void* ptr, std::size_t size)` to simply call
146
- `operator delete(ptr)`.
147
 
148
- *Default behavior:* the function
149
- `operator delete(void* ptr, std::size_t size)` calls
150
- `operator delete(ptr)`. See the note in the above *Replaceable*
151
- paragraph.
 
 
152
 
153
  *Default behavior:* If `ptr` is null, does nothing. Otherwise, reclaims
154
  the storage allocated by the earlier call to `operator new`.
155
 
156
  *Remarks:* It is unspecified under what conditions part or all of such
157
  reclaimed storage will be allocated by subsequent calls to
158
- `operator new` or any of `calloc`, `malloc`, or `realloc`, declared in
159
- `<cstdlib>`.
160
 
161
  ``` cpp
162
  void operator delete(void* ptr, const std::nothrow_t&) noexcept;
163
- void operator delete(void* ptr, std::size_t size, const std::nothrow_t&) noexcept;
164
  ```
165
 
166
- *Effects:* The *deallocation
167
- function* ([[basic.stc.dynamic.deallocation]]) called by the
168
  implementation to render the value of `ptr` invalid when the constructor
169
  invoked from a nothrow placement version of the *new-expression* throws
170
  an exception.
171
 
172
- *Replaceable:* a C++program may define a function with signature
173
- `void operator delete(void* ptr, const std::nothrow_t&) noexcept` that
174
- displaces the default version defined by the C++standard library. If
175
- this function (without `size` parameter) is defined, the program should
176
- also define
177
- `void operator delete(void* ptr, std::size_t size, const std::nothrow_t&) noexcept`.
178
- If this function with `size` parameter is defined, the program shall
179
- also define the version without the `size` parameter. The default
180
- behavior below may change in the future, which will require replacing
181
- both deallocation functions when replacing the allocation function.
182
 
183
  *Requires:* If an implementation has strict pointer
184
  safety ([[basic.stc.dynamic.safety]]) then `ptr` shall be a
185
  safely-derived pointer.
186
 
187
- *Requires:* If present, the `std::size_t size` argument must equal the
188
- size argument passed to the allocation function that returned `ptr`.
 
 
 
189
 
190
- *Required behavior:* Calls to
191
- `operator delete(void* ptr, std::size_t size, const std::nothrow_t&)`
192
- may be changed to calls to
193
- `operator delete(void* ptr, const std::nothrow_t&)` without affecting
194
- memory allocation. A conforming implementation is for
195
- `operator delete(void* ptr, std::size_t size, const std::nothrow_t&)` to
196
- simply call `operator delete(void* ptr, const std::nothrow_t&)`.
197
-
198
- *Default behavior:*
199
- `operator delete(void* ptr, std::size_t size, const std::nothrow_t&)`
200
- calls `operator delete(ptr, std::nothrow)`, and
201
- `operator delete(void* ptr, const std::nothrow_t&)` calls
202
- `operator delete(ptr)`.
203
 
204
  #### Array forms <a id="new.delete.array">[[new.delete.array]]</a>
205
 
206
  ``` cpp
207
  void* operator new[](std::size_t size);
 
208
  ```
209
 
210
- *Effects:* The *allocation function* ([[basic.stc.dynamic.allocation]])
211
  called by the array form of a *new-expression* ([[expr.new]]) to
212
- allocate `size` bytes of storage suitably aligned to represent any array
213
- object of that size or smaller.[^33]
 
 
 
214
 
215
- *Replaceable:* a C++program can define a function with this function
216
- signature that displaces the default version defined by the C++standard
217
- library.
218
 
219
- *Required behavior:* Same as for `operator new(std::size_t)`. This
220
- requirement is binding on a replacement version of this function.
 
221
 
222
- *Default behavior:* Returns `operator new(size)`.
 
223
 
224
  ``` cpp
225
  void* operator new[](std::size_t size, const std::nothrow_t&) noexcept;
 
226
  ```
227
 
228
- *Effects:* Same as above, except that it is called by a placement
229
  version of a *new-expression* when a C++program prefers a null pointer
230
  result as an error indication, instead of a `bad_alloc` exception.
231
 
232
- *Replaceable:* a C++program can define a function with this function
233
- signature that displaces the default version defined by the C++standard
234
- library.
235
 
236
  *Required behavior:* Return a non-null pointer to suitably aligned
237
- storage ([[basic.stc.dynamic]]), or return a null pointer. This
238
- requirement is binding on a replacement version of this function.
 
 
 
239
 
240
- *Default behavior:* Calls `operator new[](size)`. If the call returns
 
241
  normally, returns the result of that call. Otherwise, returns a null
242
  pointer.
243
 
244
  ``` cpp
245
  void operator delete[](void* ptr) noexcept;
246
  void operator delete[](void* ptr, std::size_t size) noexcept;
 
 
247
  ```
248
 
249
- *Effects:* The *deallocation
250
- function* ([[basic.stc.dynamic.deallocation]]) called by the array form
251
  of a *delete-expression* to render the value of `ptr` invalid.
252
 
253
- *Replaceable:* a C++program can define a function with signature
254
- `void operator delete[](void* ptr) noexcept` that displaces the default
255
- version defined by the C++standard library. If this function (without
256
- `size` parameter) is defined, the program should also define
257
- `void operator delete[](void* ptr, std::size_t size) noexcept`. If this
258
- function with `size` parameter is defined, the program shall also define
259
- the version without the `size` parameter. The default behavior below may
260
- change in the future, which will require replacing both deallocation
261
- functions when replacing the allocation function.
262
 
263
- *Requires:* *ptr* shall be a null pointer or its value shall be the
264
- value returned by an earlier call to `operator new[](std::size_t)` or
265
- `operator new[](std::size_t,const std::nothrow_t&)` which has not been
266
- invalidated by an intervening call to `operator delete[](void*)`.
267
 
268
- *Requires:* If present, the `std::size_t size` argument must equal the
269
- size argument passed to the allocation function that returned `ptr`.
 
270
 
271
- *Required behavior:* Calls to
272
- `operator delete[](void* ptr, std::size_t size)` may be changed to calls
273
- to `operator delete[](void* ptr)` without affecting memory allocation. A
274
- conforming implementation is for
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
275
  `operator delete[](void* ptr, std::size_t size)` to simply call
276
- `operator delete[](void* ptr)`.
277
 
278
- *Requires:* If an implementation has strict pointer
279
- safety ([[basic.stc.dynamic.safety]]) then `ptr` shall be a
280
- safely-derived pointer.
281
-
282
- *Default behavior:* `operator delete[](void* ptr, std::size_t size)`
283
- calls `operator delete[](ptr)`, and `operator delete[](void* ptr)` calls
284
- `operator delete(ptr)`.
285
 
286
  ``` cpp
287
  void operator delete[](void* ptr, const std::nothrow_t&) noexcept;
288
- void operator delete[](void* ptr, std::size_t size, const std::nothrow_t&) noexcept;
289
  ```
290
 
291
- *Effects:* The *deallocation
292
- function* ([[basic.stc.dynamic.deallocation]]) called by the
293
  implementation to render the value of `ptr` invalid when the constructor
294
  invoked from a nothrow placement version of the array *new-expression*
295
  throws an exception.
296
 
297
- *Replaceable:* a C++program may define a function with signature
298
- `void operator delete[](void* ptr, const std::nothrow_t&) noexcept` that
299
- displaces the default version defined by the C++standard library. If
300
- this function (without `size` parameter) is defined, the program should
301
- also define
302
- `void operator delete[](void* ptr, std::size_t size, const std::nothrow_t&) noexcept`.
303
- If this function with `size` parameter is defined, the program shall
304
- also define the version without the `size` parameter. The default
305
- behavior below may change in the future, which will require replacing
306
- both deallocation functions when replacing the allocation function.
307
 
308
  *Requires:* If an implementation has strict pointer
309
  safety ([[basic.stc.dynamic.safety]]) then `ptr` shall be a
310
  safely-derived pointer.
311
 
312
- *Requires:* If present, the `std::size_t size` argument must equal the
313
- size argument passed to the allocation function that returned `ptr`.
 
 
 
314
 
315
- *Required behavior:* Calls to
316
- `operator delete[](void* ptr, std::size_t size, const std::nothrow_t&)`
317
- may be changed to calls to
318
- `operator delete[](void* ptr, const std::nothrow_t&)` without affecting
319
- memory allocation. A conforming implementation is for
320
- `operator delete[](void* ptr, std::size_t size, const std::nothrow_t&)`
321
- to simply call `operator delete[](void* ptr, const std::nothrow_t&)`.
322
 
323
- *Default behavior:*
324
- `operator delete[](void* ptr, std::size_t size, const std::nothrow_t&)`
325
- calls `operator delete[](ptr, std::nothrow)`, and
326
- `operator delete[](void* ptr, const std::nothrow_t&)` calls
327
- `operator delete[](ptr)`.
328
 
329
- #### Placement forms <a id="new.delete.placement">[[new.delete.placement]]</a>
330
-
331
- These functions are reserved, a C++program may not define functions that
332
- displace the versions in the Standard C++library ([[constraints]]). The
333
- provisions of ([[basic.stc.dynamic]]) do not apply to these reserved
334
  placement forms of `operator new` and `operator delete`.
335
 
336
  ``` cpp
337
  void* operator new(std::size_t size, void* ptr) noexcept;
338
  ```
339
 
340
  *Returns:* `ptr`.
341
 
342
  *Remarks:* Intentionally performs no other action.
343
 
 
 
344
  This can be useful for constructing an object at a known address:
345
 
346
  ``` cpp
347
  void* place = operator new(sizeof(Something));
348
  Something* p = new (place) Something();
349
  ```
350
 
 
 
351
  ``` cpp
352
  void* operator new[](std::size_t size, void* ptr) noexcept;
353
  ```
354
 
355
  *Returns:* `ptr`.
@@ -365,11 +424,11 @@ void operator delete(void* ptr, void*) noexcept;
365
  *Requires:* If an implementation has strict pointer
366
  safety ([[basic.stc.dynamic.safety]]) then `ptr` shall be a
367
  safely-derived pointer.
368
 
369
  *Remarks:* Default function called when any part of the initialization
370
- in a placement new expression that invokes the library’s non-array
371
  placement operator new terminates by throwing an
372
  exception ([[expr.new]]).
373
 
374
  ``` cpp
375
  void operator delete[](void* ptr, void*) noexcept;
@@ -380,25 +439,27 @@ void operator delete[](void* ptr, void*) noexcept;
380
  *Requires:* If an implementation has strict pointer
381
  safety ([[basic.stc.dynamic.safety]]) then `ptr` shall be a
382
  safely-derived pointer.
383
 
384
  *Remarks:* Default function called when any part of the initialization
385
- in a placement new expression that invokes the library’s array placement
386
- operator new terminates by throwing an exception ([[expr.new]]).
 
387
 
388
  #### Data races <a id="new.delete.dataraces">[[new.delete.dataraces]]</a>
389
 
390
  For purposes of determining the existence of data races, the library
391
  versions of `operator new`, user replacement versions of global
392
- `operator new`, the C standard library functions `calloc` and `malloc`,
393
- the library versions of `operator delete`, user replacement versions of
394
- `operator delete`, the C standard library function `free`, and the C
395
- standard library function `realloc` shall not introduce a data race (
396
- [[res.on.data.races]]). Calls to these functions that allocate or
397
- deallocate a particular unit of storage shall occur in a single total
398
- order, and each such deallocation call shall happen before (
399
- [[intro.multithread]]) the next allocation (if any) in this order.
 
400
 
401
  ### Storage allocation errors <a id="alloc.errors">[[alloc.errors]]</a>
402
 
403
  #### Class `bad_alloc` <a id="bad.alloc">[[bad.alloc]]</a>
404
 
@@ -407,11 +468,11 @@ namespace std {
407
  class bad_alloc : public exception {
408
  public:
409
  bad_alloc() noexcept;
410
  bad_alloc(const bad_alloc&) noexcept;
411
  bad_alloc& operator=(const bad_alloc&) noexcept;
412
- virtual const char* what() const noexcept;
413
  };
414
  }
415
  ```
416
 
417
  The class `bad_alloc` defines the type of objects thrown as exceptions
@@ -421,55 +482,64 @@ by the implementation to report a failure to allocate storage.
421
  bad_alloc() noexcept;
422
  ```
423
 
424
  *Effects:* Constructs an object of class `bad_alloc`.
425
 
426
- *Remarks:* The result of calling `what()` on the newly constructed
427
- object is implementation-defined.
428
-
429
  ``` cpp
430
  bad_alloc(const bad_alloc&) noexcept;
431
  bad_alloc& operator=(const bad_alloc&) noexcept;
432
  ```
433
 
434
  *Effects:* Copies an object of class `bad_alloc`.
435
 
436
  ``` cpp
437
- virtual const char* what() const noexcept;
438
  ```
439
 
440
  *Returns:* An *implementation-defined* NTBS.
441
 
 
 
 
 
442
  #### Class `bad_array_new_length` <a id="new.badlength">[[new.badlength]]</a>
443
 
444
  ``` cpp
445
  namespace std {
446
  class bad_array_new_length : public bad_alloc {
447
  public:
448
  bad_array_new_length() noexcept;
 
449
  };
450
  }
451
  ```
452
 
453
  The class `bad_array_new_length` defines the type of objects thrown as
454
  exceptions by the implementation to report an attempt to allocate an
455
- array of size less than zero or greater than an implementation-defined
456
  limit ([[expr.new]]).
457
 
458
  ``` cpp
459
  bad_array_new_length() noexcept;
460
  ```
461
 
462
  *Effects:* constructs an object of class `bad_array_new_length`.
463
 
464
- *Remarks:* the result of calling `what()` on the newly constructed
465
- object is implementation-defined.
 
 
 
 
 
 
 
466
 
467
  #### Type `new_handler` <a id="new.handler">[[new.handler]]</a>
468
 
469
  ``` cpp
470
- typedef void (*new_handler)();
471
  ```
472
 
473
  The type of a *handler function* to be called by `operator new()` or
474
  `operator new[]()` ([[new.delete]]) when they cannot satisfy a request
475
  for additional storage.
@@ -477,11 +547,11 @@ for additional storage.
477
  *Required behavior:* A `new_handler` shall perform one of the following:
478
 
479
  - make more storage available for allocation and then return;
480
  - throw an exception of type `bad_alloc` or a class derived from
481
  `bad_alloc`;
482
- - terminate execution of the program without returning to the caller;
483
 
484
  #### `set_new_handler` <a id="set.new.handler">[[set.new.handler]]</a>
485
 
486
  ``` cpp
487
  new_handler set_new_handler(new_handler new_p) noexcept;
@@ -498,7 +568,98 @@ new_handler set_new_handler(new_handler new_p) noexcept;
498
 
499
  ``` cpp
500
  new_handler get_new_handler() noexcept;
501
  ```
502
 
503
- *Returns:* The current `new_handler`. This may be a null pointer value.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
504
 
 
2
 
3
  The header `<new>` defines several functions that manage the allocation
4
  of dynamic storage in a program. It also defines components for
5
  reporting storage management errors.
6
 
7
+ ### Header `<new>` synopsis <a id="new.syn">[[new.syn]]</a>
8
+
9
  ``` cpp
10
  namespace std {
11
  class bad_alloc;
12
  class bad_array_new_length;
13
+ enum class align_val_t : size_t {};
14
+ struct nothrow_t { explicit nothrow_t() = default; };
15
  extern const nothrow_t nothrow;
16
+ using new_handler = void (*)();
17
  new_handler get_new_handler() noexcept;
18
  new_handler set_new_handler(new_handler new_p) noexcept;
19
+
20
+ // [ptr.launder], pointer optimization barrier
21
+ template <class T> constexpr T* launder(T* p) noexcept;
22
+
23
+ // [hardware.interference], hardware interference size
24
+ inline constexpr size_t hardware_destructive_interference_size = implementation-defined{};
25
+ inline constexpr size_t hardware_constructive_interference_size = implementation-defined{};
26
  }
27
 
28
  void* operator new(std::size_t size);
29
+ void* operator new(std::size_t size, std::align_val_t alignment);
30
  void* operator new(std::size_t size, const std::nothrow_t&) noexcept;
31
+ void* operator new(std::size_t size, std::align_val_t alignment,
32
+ const std::nothrow_t&) noexcept;
33
  void operator delete(void* ptr) noexcept;
 
34
  void operator delete(void* ptr, std::size_t size) noexcept;
35
+ void operator delete(void* ptr, std::align_val_t alignment) noexcept;
36
+ void operator delete(void* ptr, std::size_t size, std::align_val_t alignment) noexcept;
37
+ void operator delete(void* ptr, const std::nothrow_t&) noexcept;
38
+ void operator delete(void* ptr, std::align_val_t alignment,
39
  const std::nothrow_t&) noexcept;
40
  void* operator new[](std::size_t size);
41
+ void* operator new[](std::size_t size, std::align_val_t alignment);
42
  void* operator new[](std::size_t size, const std::nothrow_t&) noexcept;
43
+ void* operator new[](std::size_t size, std::align_val_t alignment,
44
+ const std::nothrow_t&) noexcept;
45
  void operator delete[](void* ptr) noexcept;
 
46
  void operator delete[](void* ptr, std::size_t size) noexcept;
47
+ void operator delete[](void* ptr, std::align_val_t alignment) noexcept;
48
+ void operator delete[](void* ptr, std::size_t size, std::align_val_t alignment) noexcept;
49
+ void operator delete[](void* ptr, const std::nothrow_t&) noexcept;
50
+ void operator delete[](void* ptr, std::align_val_t alignment,
51
  const std::nothrow_t&) noexcept;
52
 
53
  void* operator new (std::size_t size, void* ptr) noexcept;
54
  void* operator new[](std::size_t size, void* ptr) noexcept;
55
  void operator delete (void* ptr, void*) noexcept;
 
59
    [[intro.memory]], [[basic.stc.dynamic]], [[expr.new]],
60
  [[expr.delete]], [[class.free]], [[memory]].
61
 
62
  ### Storage allocation and deallocation <a id="new.delete">[[new.delete]]</a>
63
 
64
+ Except where otherwise specified, the provisions of 
65
+ [[basic.stc.dynamic]] apply to the library versions of `operator new`
66
  and `operator
67
+ delete`. If the value of an alignment argument passed to any of these
68
+ functions is not a valid alignment value, the behavior is undefined.
69
 
70
  #### Single-object forms <a id="new.delete.single">[[new.delete.single]]</a>
71
 
72
  ``` cpp
73
  void* operator new(std::size_t size);
74
+ void* operator new(std::size_t size, std::align_val_t alignment);
75
  ```
76
 
77
+ *Effects:* The allocation functions ([[basic.stc.dynamic.allocation]])
78
  called by a *new-expression* ([[expr.new]]) to allocate `size` bytes of
79
+ storage. The second form is called for a type with new-extended
80
+ alignment, and allocates storage with the specified alignment. The first
81
+ form is called otherwise, and allocates storage suitably aligned to
82
+ represent any object of that size provided the object’s type does not
83
+ have new-extended alignment.
84
 
85
+ *Replaceable:* A C++program may define functions with either of these
86
+ function signatures, and thereby displace the default versions defined
87
+ by the C++standard library.
88
 
89
  *Required behavior:* Return a non-null pointer to suitably aligned
90
  storage ([[basic.stc.dynamic]]), or else throw a `bad_alloc` exception.
91
+ This requirement is binding on any replacement versions of these
92
+ functions.
93
 
94
  *Default behavior:*
95
 
96
  - Executes a loop: Within the loop, the function first attempts to
97
  allocate the requested storage. Whether the attempt involves a call to
98
+ the C standard library functions `malloc` or `aligned_alloc` is
99
+ unspecified.
100
  - Returns a pointer to the allocated storage if the attempt is
101
  successful. Otherwise, if the current
102
  `new_handler` ([[get.new.handler]]) is a null pointer value, throws
103
  `bad_alloc`.
104
  - Otherwise, the function calls the current `new_handler`
 
107
  - The loop terminates when an attempt to allocate the requested storage
108
  is successful or when a called `new_handler` function does not return.
109
 
110
  ``` cpp
111
  void* operator new(std::size_t size, const std::nothrow_t&) noexcept;
112
+ void* operator new(std::size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept;
113
  ```
114
 
115
+ *Effects:* Same as above, except that these are called by a placement
116
  version of a *new-expression* when a C++program prefers a null pointer
117
  result as an error indication, instead of a `bad_alloc` exception.
118
 
119
+ *Replaceable:* A C++program may define functions with either of these
120
+ function signatures, and thereby displace the default versions defined
121
+ by the C++standard library.
122
 
123
  *Required behavior:* Return a non-null pointer to suitably aligned
124
+ storage ([[basic.stc.dynamic]]), or else return a null pointer. Each of
125
+ these nothrow versions of `operator new` returns a pointer obtained as
126
+ if acquired from the (possibly replaced) corresponding non-placement
127
+ function. This requirement is binding on any replacement versions of
128
+ these functions.
129
 
130
+ *Default behavior:* Calls `operator new(size)`, or
131
+ `operator new(size, alignment)`, respectively. If the call returns
132
  normally, returns the result of that call. Otherwise, returns a null
133
  pointer.
134
 
135
+ [*Example 1*:
136
+
137
  ``` cpp
138
  T* p1 = new T; // throws bad_alloc if it fails
139
  T* p2 = new(nothrow) T; // returns nullptr if it fails
140
  ```
141
 
142
+ — *end example*]
143
+
144
  ``` cpp
145
  void operator delete(void* ptr) noexcept;
146
  void operator delete(void* ptr, std::size_t size) noexcept;
147
+ void operator delete(void* ptr, std::align_val_t alignment) noexcept;
148
+ void operator delete(void* ptr, std::size_t size, std::align_val_t alignment) noexcept;
149
  ```
150
 
151
+ *Effects:* The deallocation
152
+ functions ([[basic.stc.dynamic.deallocation]]) called by a
153
  *delete-expression* to render the value of `ptr` invalid.
154
 
155
+ *Replaceable:* A C++program may define functions with any of these
156
+ function signatures, and thereby displace the default versions defined
157
+ by the C++standard library.
 
 
 
 
 
 
158
 
159
+ If a function without a `size` parameter is defined, the program should
160
+ also define the corresponding function with a `size` parameter. If a
161
+ function with a `size` parameter is defined, the program shall also
162
+ define the corresponding version without the `size` parameter.
163
+
164
+ [*Note 1*: The default behavior below may change in the future, which
165
+ will require replacing both deallocation functions when replacing the
166
+ allocation function. — *end note*]
167
+
168
+ *Requires:* `ptr` shall be a null pointer or its value shall represent
169
+ the address of a block of memory allocated by an earlier call to a
170
+ (possibly replaced) `operator new(std::size_t)` or
171
+ `operator new(std::size_t, std::align_val_t)` which has not been
172
+ invalidated by an intervening call to `operator delete`.
173
 
174
  *Requires:* If an implementation has strict pointer
175
  safety ([[basic.stc.dynamic.safety]]) then `ptr` shall be a
176
  safely-derived pointer.
177
 
178
+ *Requires:* If the `alignment` parameter is not present, `ptr` shall
179
+ have been returned by an allocation function without an `alignment`
180
+ parameter. If present, the `alignment` argument shall equal the
181
+ `alignment` argument passed to the allocation function that returned
182
+ `ptr`. If present, the `size` argument shall equal the `size` argument
183
+ passed to the allocation function that returned `ptr`.
184
 
185
+ *Required behavior:* A call to an `operator delete` with a `size`
186
+ parameter may be changed to a call to the corresponding
187
+ `operator delete` without a `size` parameter, without affecting memory
188
+ allocation.
189
+
190
+ [*Note 2*: A conforming implementation is for
191
  `operator delete(void* ptr, std::size_t size)` to simply call
192
+ `operator delete(ptr)`. — *end note*]
193
 
194
+ *Default behavior:* The functions that have a `size` parameter forward
195
+ their other parameters to the corresponding function without a `size`
196
+ parameter.
197
+
198
+ [*Note 3*: See the note in the above *Replaceable:*
199
+ paragraph. — *end note*]
200
 
201
  *Default behavior:* If `ptr` is null, does nothing. Otherwise, reclaims
202
  the storage allocated by the earlier call to `operator new`.
203
 
204
  *Remarks:* It is unspecified under what conditions part or all of such
205
  reclaimed storage will be allocated by subsequent calls to
206
+ `operator new` or any of `aligned_alloc`, `calloc`, `malloc`, or
207
+ `realloc`, declared in `<cstdlib>`.
208
 
209
  ``` cpp
210
  void operator delete(void* ptr, const std::nothrow_t&) noexcept;
211
+ void operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept;
212
  ```
213
 
214
+ *Effects:* The deallocation
215
+ functions ([[basic.stc.dynamic.deallocation]]) called by the
216
  implementation to render the value of `ptr` invalid when the constructor
217
  invoked from a nothrow placement version of the *new-expression* throws
218
  an exception.
219
 
220
+ *Replaceable:* A C++program may define functions with either of these
221
+ function signatures, and thereby displace the default versions defined
222
+ by the C++standard library.
223
+
224
+ *Requires:* `ptr` shall be a null pointer or its value shall represent
225
+ the address of a block of memory allocated by an earlier call to a
226
+ (possibly replaced) `operator new(std::size_t)` or
227
+ `operator new(std::size_t, std::align_val_t)` which has not been
228
+ invalidated by an intervening call to `operator delete`.
 
229
 
230
  *Requires:* If an implementation has strict pointer
231
  safety ([[basic.stc.dynamic.safety]]) then `ptr` shall be a
232
  safely-derived pointer.
233
 
234
+ *Requires:* If the `alignment` parameter is not present, `ptr` shall
235
+ have been returned by an allocation function without an `alignment`
236
+ parameter. If present, the `alignment` argument shall equal the
237
+ `alignment` argument passed to the allocation function that returned
238
+ `ptr`.
239
 
240
+ *Default behavior:* Calls `operator delete(ptr)`, or
241
+ `operator delete(ptr, alignment)`, respectively.
 
 
 
 
 
 
 
 
 
 
 
242
 
243
  #### Array forms <a id="new.delete.array">[[new.delete.array]]</a>
244
 
245
  ``` cpp
246
  void* operator new[](std::size_t size);
247
+ void* operator new[](std::size_t size, std::align_val_t alignment);
248
  ```
249
 
250
+ *Effects:* The allocation functions ([[basic.stc.dynamic.allocation]])
251
  called by the array form of a *new-expression* ([[expr.new]]) to
252
+ allocate `size` bytes of storage. The second form is called for a type
253
+ with new-extended alignment, and allocates storage with the specified
254
+ alignment. The first form is called otherwise, and allocates storage
255
+ suitably aligned to represent any array object of that size or smaller,
256
+ provided the object’s type does not have new-extended alignment. [^33]
257
 
258
+ *Replaceable:* A C++program may define functions with either of these
259
+ function signatures, and thereby displace the default versions defined
260
+ by the C++standard library.
261
 
262
+ *Required behavior:* Same as for the corresponding single-object forms.
263
+ This requirement is binding on any replacement versions of these
264
+ functions.
265
 
266
+ *Default behavior:* Returns `operator new(size)`, or
267
+ `operator new(size, alignment)`, respectively.
268
 
269
  ``` cpp
270
  void* operator new[](std::size_t size, const std::nothrow_t&) noexcept;
271
+ void* operator new[](std::size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept;
272
  ```
273
 
274
+ *Effects:* Same as above, except that these are called by a placement
275
  version of a *new-expression* when a C++program prefers a null pointer
276
  result as an error indication, instead of a `bad_alloc` exception.
277
 
278
+ *Replaceable:* A C++program may define functions with either of these
279
+ function signatures, and thereby displace the default versions defined
280
+ by the C++standard library.
281
 
282
  *Required behavior:* Return a non-null pointer to suitably aligned
283
+ storage ([[basic.stc.dynamic]]), or else return a null pointer. Each of
284
+ these nothrow versions of `operator new[]` returns a pointer obtained as
285
+ if acquired from the (possibly replaced) corresponding non-placement
286
+ function. This requirement is binding on any replacement versions of
287
+ these functions.
288
 
289
+ *Default behavior:* Calls `operator new[](size)`, or
290
+ `operator new[](size, alignment)`, respectively. If the call returns
291
  normally, returns the result of that call. Otherwise, returns a null
292
  pointer.
293
 
294
  ``` cpp
295
  void operator delete[](void* ptr) noexcept;
296
  void operator delete[](void* ptr, std::size_t size) noexcept;
297
+ void operator delete[](void* ptr, std::align_val_t alignment) noexcept;
298
+ void operator delete[](void* ptr, std::size_t size, std::align_val_t alignment) noexcept;
299
  ```
300
 
301
+ *Effects:* The deallocation
302
+ functions ([[basic.stc.dynamic.deallocation]]) called by the array form
303
  of a *delete-expression* to render the value of `ptr` invalid.
304
 
305
+ *Replaceable:* A C++program may define functions with any of these
306
+ function signatures, and thereby displace the default versions defined
307
+ by the C++standard library.
 
 
 
 
 
 
308
 
309
+ If a function without a `size` parameter is defined, the program should
310
+ also define the corresponding function with a `size` parameter. If a
311
+ function with a `size` parameter is defined, the program shall also
312
+ define the corresponding version without the `size` parameter.
313
 
314
+ [*Note 1*: The default behavior below may change in the future, which
315
+ will require replacing both deallocation functions when replacing the
316
+ allocation function. — *end note*]
317
 
318
+ *Requires:* `ptr` shall be a null pointer or its value shall represent
319
+ the address of a block of memory allocated by an earlier call to a
320
+ (possibly replaced) `operator new[](std::size_t)` or
321
+ `operator new[](std::size_t, std::align_val_t)` which has not been
322
+ invalidated by an intervening call to `operator delete[]`.
323
+
324
+ *Requires:* If an implementation has strict pointer
325
+ safety ([[basic.stc.dynamic.safety]]) then `ptr` shall be a
326
+ safely-derived pointer.
327
+
328
+ *Requires:* If the `alignment` parameter is not present, `ptr` shall
329
+ have been returned by an allocation function without an `alignment`
330
+ parameter. If present, the `alignment` argument shall equal the
331
+ `alignment` argument passed to the allocation function that returned
332
+ `ptr`. If present, the `size` argument shall equal the `size` argument
333
+ passed to the allocation function that returned `ptr`.
334
+
335
+ *Required behavior:* A call to an `operator delete[]` with a `size`
336
+ parameter may be changed to a call to the corresponding
337
+ `operator delete[]` without a `size` parameter, without affecting memory
338
+ allocation.
339
+
340
+ [*Note 2*: A conforming implementation is for
341
  `operator delete[](void* ptr, std::size_t size)` to simply call
342
+ `operator delete[](ptr)`. — *end note*]
343
 
344
+ *Default behavior:* The functions that have a `size` parameter forward
345
+ their other parameters to the corresponding function without a `size`
346
+ parameter. The functions that do not have a `size` parameter forward
347
+ their parameters to the corresponding `operator delete` (single-object)
348
+ function.
 
 
349
 
350
  ``` cpp
351
  void operator delete[](void* ptr, const std::nothrow_t&) noexcept;
352
+ void operator delete[](void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept;
353
  ```
354
 
355
+ *Effects:* The deallocation
356
+ functions ([[basic.stc.dynamic.deallocation]]) called by the
357
  implementation to render the value of `ptr` invalid when the constructor
358
  invoked from a nothrow placement version of the array *new-expression*
359
  throws an exception.
360
 
361
+ *Replaceable:* A C++program may define functions with either of these
362
+ function signatures, and thereby displace the default versions defined
363
+ by the C++standard library.
364
+
365
+ *Requires:* `ptr` shall be a null pointer or its value shall represent
366
+ the address of a block of memory allocated by an earlier call to a
367
+ (possibly replaced) `operator new[](std::size_t)` or
368
+ `operator new[](std::size_t, std::align_val_t)` which has not been
369
+ invalidated by an intervening call to `operator delete[]`.
 
370
 
371
  *Requires:* If an implementation has strict pointer
372
  safety ([[basic.stc.dynamic.safety]]) then `ptr` shall be a
373
  safely-derived pointer.
374
 
375
+ *Requires:* If the `alignment` parameter is not present, `ptr` shall
376
+ have been returned by an allocation function without an `alignment`
377
+ parameter. If present, the `alignment` argument shall equal the
378
+ `alignment` argument passed to the allocation function that returned
379
+ `ptr`.
380
 
381
+ *Default behavior:* Calls `operator delete[](ptr)`, or
382
+ `operator delete[](ptr, alignment)`, respectively.
 
 
 
 
 
383
 
384
+ #### Non-allocating forms <a id="new.delete.placement">[[new.delete.placement]]</a>
 
 
 
 
385
 
386
+ These functions are reserved; a C++program may not define functions that
387
+ displace the versions in the C++standard library ([[constraints]]). The
388
+ provisions of  [[basic.stc.dynamic]] do not apply to these reserved
 
 
389
  placement forms of `operator new` and `operator delete`.
390
 
391
  ``` cpp
392
  void* operator new(std::size_t size, void* ptr) noexcept;
393
  ```
394
 
395
  *Returns:* `ptr`.
396
 
397
  *Remarks:* Intentionally performs no other action.
398
 
399
+ [*Example 1*:
400
+
401
  This can be useful for constructing an object at a known address:
402
 
403
  ``` cpp
404
  void* place = operator new(sizeof(Something));
405
  Something* p = new (place) Something();
406
  ```
407
 
408
+ — *end example*]
409
+
410
  ``` cpp
411
  void* operator new[](std::size_t size, void* ptr) noexcept;
412
  ```
413
 
414
  *Returns:* `ptr`.
 
424
  *Requires:* If an implementation has strict pointer
425
  safety ([[basic.stc.dynamic.safety]]) then `ptr` shall be a
426
  safely-derived pointer.
427
 
428
  *Remarks:* Default function called when any part of the initialization
429
+ in a placement *new-expression* that invokes the library’s non-array
430
  placement operator new terminates by throwing an
431
  exception ([[expr.new]]).
432
 
433
  ``` cpp
434
  void operator delete[](void* ptr, void*) noexcept;
 
439
  *Requires:* If an implementation has strict pointer
440
  safety ([[basic.stc.dynamic.safety]]) then `ptr` shall be a
441
  safely-derived pointer.
442
 
443
  *Remarks:* Default function called when any part of the initialization
444
+ in a placement *new-expression* that invokes the library’s array
445
+ placement operator new terminates by throwing an
446
+ exception ([[expr.new]]).
447
 
448
  #### Data races <a id="new.delete.dataraces">[[new.delete.dataraces]]</a>
449
 
450
  For purposes of determining the existence of data races, the library
451
  versions of `operator new`, user replacement versions of global
452
+ `operator new`, the C standard library functions `aligned_alloc`,
453
+ `calloc`, and `malloc`, the library versions of `operator delete`, user
454
+ replacement versions of `operator delete`, the C standard library
455
+ function `free`, and the C standard library function `realloc` shall not
456
+ introduce a data race ([[res.on.data.races]]). Calls to these functions
457
+ that allocate or deallocate a particular unit of storage shall occur in
458
+ a single total order, and each such deallocation call shall happen
459
+ before ([[intro.multithread]]) the next allocation (if any) in this
460
+ order.
461
 
462
  ### Storage allocation errors <a id="alloc.errors">[[alloc.errors]]</a>
463
 
464
  #### Class `bad_alloc` <a id="bad.alloc">[[bad.alloc]]</a>
465
 
 
468
  class bad_alloc : public exception {
469
  public:
470
  bad_alloc() noexcept;
471
  bad_alloc(const bad_alloc&) noexcept;
472
  bad_alloc& operator=(const bad_alloc&) noexcept;
473
+ const char* what() const noexcept override;
474
  };
475
  }
476
  ```
477
 
478
  The class `bad_alloc` defines the type of objects thrown as exceptions
 
482
  bad_alloc() noexcept;
483
  ```
484
 
485
  *Effects:* Constructs an object of class `bad_alloc`.
486
 
 
 
 
487
  ``` cpp
488
  bad_alloc(const bad_alloc&) noexcept;
489
  bad_alloc& operator=(const bad_alloc&) noexcept;
490
  ```
491
 
492
  *Effects:* Copies an object of class `bad_alloc`.
493
 
494
  ``` cpp
495
+ const char* what() const noexcept override;
496
  ```
497
 
498
  *Returns:* An *implementation-defined* NTBS.
499
 
500
+ *Remarks:* The message may be a null-terminated multibyte
501
+ string ([[multibyte.strings]]), suitable for conversion and display as
502
+ a `wstring` ([[string.classes]], [[locale.codecvt]]).
503
+
504
  #### Class `bad_array_new_length` <a id="new.badlength">[[new.badlength]]</a>
505
 
506
  ``` cpp
507
  namespace std {
508
  class bad_array_new_length : public bad_alloc {
509
  public:
510
  bad_array_new_length() noexcept;
511
+ const char* what() const noexcept override;
512
  };
513
  }
514
  ```
515
 
516
  The class `bad_array_new_length` defines the type of objects thrown as
517
  exceptions by the implementation to report an attempt to allocate an
518
+ array of size less than zero or greater than an *implementation-defined*
519
  limit ([[expr.new]]).
520
 
521
  ``` cpp
522
  bad_array_new_length() noexcept;
523
  ```
524
 
525
  *Effects:* constructs an object of class `bad_array_new_length`.
526
 
527
+ ``` cpp
528
+ const char* what() const noexcept override;
529
+ ```
530
+
531
+ *Returns:* An *implementation-defined* NTBS.
532
+
533
+ *Remarks:* The message may be a null-terminated multibyte
534
+ string ([[multibyte.strings]]), suitable for conversion and display as
535
+ a `wstring` ([[string.classes]], [[locale.codecvt]]).
536
 
537
  #### Type `new_handler` <a id="new.handler">[[new.handler]]</a>
538
 
539
  ``` cpp
540
+ using new_handler = void (*)();
541
  ```
542
 
543
  The type of a *handler function* to be called by `operator new()` or
544
  `operator new[]()` ([[new.delete]]) when they cannot satisfy a request
545
  for additional storage.
 
547
  *Required behavior:* A `new_handler` shall perform one of the following:
548
 
549
  - make more storage available for allocation and then return;
550
  - throw an exception of type `bad_alloc` or a class derived from
551
  `bad_alloc`;
552
+ - terminate execution of the program without returning to the caller.
553
 
554
  #### `set_new_handler` <a id="set.new.handler">[[set.new.handler]]</a>
555
 
556
  ``` cpp
557
  new_handler set_new_handler(new_handler new_p) noexcept;
 
568
 
569
  ``` cpp
570
  new_handler get_new_handler() noexcept;
571
  ```
572
 
573
+ *Returns:* The current `new_handler`.
574
+
575
+ [*Note 1*: This may be a null pointer value. — *end note*]
576
+
577
+ ### Pointer optimization barrier <a id="ptr.launder">[[ptr.launder]]</a>
578
+
579
+ ``` cpp
580
+ template <class T> constexpr T* launder(T* p) noexcept;
581
+ ```
582
+
583
+ *Requires:* `p` represents the address *A* of a byte in memory. An
584
+ object *X* that is within its lifetime ([[basic.life]]) and whose type
585
+ is similar ([[conv.qual]]) to `T` is located at the address *A*. All
586
+ bytes of storage that would be reachable through the result are
587
+ reachable through `p` (see below).
588
+
589
+ *Returns:* A value of type `T *` that points to `X`.
590
+
591
+ *Remarks:* An invocation of this function may be used in a core constant
592
+ expression whenever the value of its argument may be used in a core
593
+ constant expression. A byte of storage is reachable through a pointer
594
+ value that points to an object *Y* if it is within the storage occupied
595
+ by *Y*, an object that is pointer-interconvertible with *Y*, or the
596
+ immediately-enclosing array object if *Y* is an array element. The
597
+ program is ill-formed if `T` is a function type or cv `void`.
598
+
599
+ [*Note 1*: If a new object is created in storage occupied by an
600
+ existing object of the same type, a pointer to the original object can
601
+ be used to refer to the new object unless the type contains `const` or
602
+ reference members; in the latter cases, this function can be used to
603
+ obtain a usable pointer to the new object.
604
+ See  [[basic.life]]. — *end note*]
605
+
606
+ [*Example 1*:
607
+
608
+ ``` cpp
609
+ struct X { const int n; };
610
+ X *p = new X{3};
611
+ const int a = p->n;
612
+ new (p) X{5}; // p does not point to new object ([basic.life]) because X::n is const
613
+ const int b = p->n; // undefined behavior
614
+ const int c = std::launder(p)->n; // OK
615
+ ```
616
+
617
+ — *end example*]
618
+
619
+ ### Hardware interference size <a id="hardware.interference">[[hardware.interference]]</a>
620
+
621
+ ``` cpp
622
+ inline constexpr size_t hardware_destructive_interference_size = implementation-defined{};
623
+ ```
624
+
625
+ This number is the minimum recommended offset between two
626
+ concurrently-accessed objects to avoid additional performance
627
+ degradation due to contention introduced by the implementation. It shall
628
+ be at least `alignof(max_align_t)`.
629
+
630
+ [*Example 1*:
631
+
632
+ ``` cpp
633
+ struct keep_apart {
634
+ alignas(hardware_destructive_interference_size) atomic<int> cat;
635
+ alignas(hardware_destructive_interference_size) atomic<int> dog;
636
+ };
637
+ ```
638
+
639
+ — *end example*]
640
+
641
+ ``` cpp
642
+ inline constexpr size_t hardware_constructive_interference_size = implementation-defined{};
643
+ ```
644
+
645
+ This number is the maximum recommended size of contiguous memory
646
+ occupied by two objects accessed with temporal locality by concurrent
647
+ threads. It shall be at least `alignof(max_align_t)`.
648
+
649
+ [*Example 2*:
650
+
651
+ ``` cpp
652
+ struct together {
653
+ atomic<int> dog;
654
+ int puppy;
655
+ };
656
+ struct kennel {
657
+ // Other data members...
658
+ alignas(sizeof(together)) together pack;
659
+ // Other data members...
660
+ };
661
+ static_assert(sizeof(together) <= hardware_constructive_interference_size);
662
+ ```
663
+
664
+ — *end example*]
665