495 lines
23 KiB
Markdown
495 lines
23 KiB
Markdown
[basic.stc]
|
||
|
||
# 6 Basics [[basic]](./#basic)
|
||
|
||
## 6.8 Memory and objects [[basic.memobj]](basic.memobj#basic.stc)
|
||
|
||
### 6.8.6 Storage duration [basic.stc]
|
||
|
||
#### [6.8.6.1](#general) General [[basic.stc.general]](basic.stc.general)
|
||
|
||
[1](#general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4244)
|
||
|
||
The [*storage duration*](#def:storage_duration "6.8.6.1 General [basic.stc.general]") is the property of an object that defines the minimum
|
||
potential lifetime of the storage containing the object[.](#general-1.sentence-1)
|
||
|
||
The storage
|
||
duration is determined by the construct used to create the object and is
|
||
one of the following:
|
||
|
||
- [(1.1)](#general-1.1)
|
||
|
||
static storage duration
|
||
|
||
- [(1.2)](#general-1.2)
|
||
|
||
thread storage duration
|
||
|
||
- [(1.3)](#general-1.3)
|
||
|
||
automatic storage duration
|
||
|
||
- [(1.4)](#general-1.4)
|
||
|
||
dynamic storage duration
|
||
|
||
[*Note [1](#general-note-1)*:
|
||
|
||
After the duration of a region of storage has ended,
|
||
the use of pointers to that region of storage is limited ([[basic.compound]](basic.compound "6.9.4 Compound types"))[.](#general-1.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[2](#general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4261)
|
||
|
||
Static, thread, and automatic storage durations are associated with objects
|
||
introduced by declarations ([[basic.def]](basic.def "6.2 Declarations and definitions")) and
|
||
with temporary objects ([[class.temporary]](class.temporary "6.8.7 Temporary objects"))[.](#general-2.sentence-1)
|
||
|
||
The dynamic storage duration
|
||
is associated with objects created by a[*new-expression*](expr.new#nt:new-expression "7.6.2.8 New [expr.new]") ([[expr.new]](expr.new "7.6.2.8 New")) or
|
||
with implicitly created objects ([[intro.object]](intro.object "6.8.2 Object model"))[.](#general-2.sentence-2)
|
||
|
||
[3](#general-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4274)
|
||
|
||
The storage duration categories apply to references as well[.](#general-3.sentence-1)
|
||
|
||
[4](#general-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4277)
|
||
|
||
The storage duration of subobjects and reference members
|
||
is that of their complete object ([[intro.object]](intro.object "6.8.2 Object model"))[.](#general-4.sentence-1)
|
||
|
||
#### [6.8.6.2](#static) Static storage duration [[basic.stc.static]](basic.stc.static)
|
||
|
||
[1](#static-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4285)
|
||
|
||
All variables which
|
||
|
||
- [(1.1)](#static-1.1)
|
||
|
||
do not have thread storage duration and
|
||
|
||
- [(1.2)](#static-1.2)
|
||
|
||
belong to a namespace scope ([[basic.scope.namespace]](basic.scope.namespace "6.4.6 Namespace scope")) or
|
||
are first declared with
|
||
the static or extern keywords ([[dcl.stc]](dcl.stc "9.2.2 Storage class specifiers"))
|
||
|
||
have [*static storage duration*](#def:storage_duration,static "6.8.6.2 Static storage duration [basic.stc.static]")[.](#static-1.sentence-1)
|
||
|
||
The storage for these entities lasts for the duration of the
|
||
program ([[basic.start.static]](basic.start.static "6.10.3.2 Static initialization"), [[basic.start.term]](basic.start.term "6.10.3.4 Termination"))[.](#static-1.sentence-2)
|
||
|
||
[2](#static-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4299)
|
||
|
||
If a variable with static storage duration has initialization or a
|
||
destructor with side effects, it shall not be eliminated even if it
|
||
appears to be unused, except that a class object or its copy/move may be
|
||
eliminated as specified in [[class.copy.elision]](class.copy.elision "11.9.6 Copy/move elision")[.](#static-2.sentence-1)
|
||
|
||
[3](#static-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4305)
|
||
|
||
[*Note [1](#static-note-1)*:
|
||
|
||
The keyword static can be used to declare
|
||
a block variable ([[basic.scope.block]](basic.scope.block "6.4.3 Block scope")) with static storage duration;[[stmt.dcl]](stmt.dcl "8.10 Declaration statement") and [[basic.start.term]](basic.start.term "6.10.3.4 Termination") describe the
|
||
initialization and destruction of such variables[.](#static-3.sentence-1)
|
||
|
||
The keyword static applied to
|
||
a class data member in a class definition
|
||
gives the data member static storage duration ([[class.static.data]](class.static.data "11.4.9.3 Static data members"))[.](#static-3.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
#### [6.8.6.3](#thread) Thread storage duration [[basic.stc.thread]](basic.stc.thread)
|
||
|
||
[1](#thread-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4320)
|
||
|
||
All variables declared with the thread_local keyword have[*thread storage duration*](#def:storage_duration,thread "6.8.6.3 Thread storage duration [basic.stc.thread]")[.](#thread-1.sentence-1)
|
||
|
||
The storage for these entities lasts for the duration of
|
||
the thread in which they are created[.](#thread-1.sentence-2)
|
||
|
||
There is a distinct object or reference
|
||
per thread, and use of the declared name refers to the entity associated with
|
||
the current thread[.](#thread-1.sentence-3)
|
||
|
||
[2](#thread-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4328)
|
||
|
||
[*Note [1](#thread-note-1)*:
|
||
|
||
A variable with thread storage duration is initialized as specified
|
||
in [[basic.start.static]](basic.start.static "6.10.3.2 Static initialization"), [[basic.start.dynamic]](basic.start.dynamic "6.10.3.3 Dynamic initialization of non-block variables"), and [[stmt.dcl]](stmt.dcl "8.10 Declaration statement") and, if constructed, is destroyed on thread exit ([[basic.start.term]](basic.start.term "6.10.3.4 Termination"))[.](#thread-2.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
#### [6.8.6.4](#auto) Automatic storage duration [[basic.stc.auto]](basic.stc.auto)
|
||
|
||
[1](#auto-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4337)
|
||
|
||
Variables that belong to a block scope and are
|
||
not explicitly declared static, thread_local, or extern have[*automatic storage duration*](#def:storage_duration,automatic "6.8.6.4 Automatic storage duration [basic.stc.auto]")[.](#auto-1.sentence-1)
|
||
|
||
The storage
|
||
for such variables lasts until the block in which they are created exits[.](#auto-1.sentence-2)
|
||
|
||
[*Note [1](#auto-note-1)*:
|
||
|
||
These variables are initialized and destroyed as described in [[stmt.dcl]](stmt.dcl "8.10 Declaration statement")[.](#auto-1.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
Variables that belong to a parameter scope also have automatic storage duration[.](#auto-1.sentence-4)
|
||
|
||
The storage for a function parameter lasts until
|
||
immediately after its destruction ([[expr.call]](expr.call "7.6.1.3 Function call"))[.](#auto-1.sentence-5)
|
||
|
||
[2](#auto-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4350)
|
||
|
||
If a variable with automatic storage duration has initialization or a destructor with side
|
||
effects, an implementation shall not destroy it before the end of its block
|
||
nor eliminate it as an optimization, even if it appears to be
|
||
unused, except that a class object or its copy/move may be eliminated as
|
||
specified in [[class.copy.elision]](class.copy.elision "11.9.6 Copy/move elision")[.](#auto-2.sentence-1)
|
||
|
||
#### [6.8.6.5](#dynamic) Dynamic storage duration [[basic.stc.dynamic]](basic.stc.dynamic)
|
||
|
||
#### [6.8.6.5.1](#dynamic.general) General [[basic.stc.dynamic.general]](basic.stc.dynamic.general)
|
||
|
||
[1](#dynamic.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4362)
|
||
|
||
Objects can be created dynamically during [program
|
||
execution](intro.execution "6.10.1 Sequential execution [intro.execution]"), using[*new-expression*](expr.new#nt:new-expression "7.6.2.8 New [expr.new]")*s* ([[expr.new]](expr.new "7.6.2.8 New")), and destroyed using[*delete-expression*](expr.delete#nt:delete-expression "7.6.2.9 Delete [expr.delete]")*s* ([[expr.delete]](expr.delete "7.6.2.9 Delete"))[.](#dynamic.general-1.sentence-1)
|
||
|
||
A C++ implementation
|
||
provides access to, and management of, dynamic storage via
|
||
the global [*allocation functions*](#def:allocation_function "6.8.6.5.1 General [basic.stc.dynamic.general]")operator new andoperator new[] and
|
||
the global [*deallocation functions*](#def:deallocation_function "6.8.6.5.1 General [basic.stc.dynamic.general]")operator delete andoperator delete[][.](#dynamic.general-1.sentence-2)
|
||
|
||
[*Note [1](#dynamic.general-note-1)*:
|
||
|
||
The non-allocating forms described in [[new.delete.placement]](new.delete.placement "17.6.3.4 Non-allocating forms") do not perform allocation or deallocation[.](#dynamic.general-1.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[2](#dynamic.general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4381)
|
||
|
||
The library provides default definitions for the global allocation and
|
||
deallocation functions[.](#dynamic.general-2.sentence-1)
|
||
|
||
Some global allocation and deallocation
|
||
functions are replaceable ([[dcl.fct.def.replace]](dcl.fct.def.replace#term.replaceable.function "9.6.5 Replaceable function definitions"))[.](#dynamic.general-2.sentence-2)
|
||
|
||
The following allocation and deallocation functions ([[support.dynamic]](support.dynamic "17.6 Dynamic memory management"))
|
||
are implicitly declared in global scope in each translation unit of a
|
||
program[.](#dynamic.general-2.sentence-3)
|
||
|
||
void* operator new(std::size_t);void* operator new(std::size_t, std::align_val_t);
|
||
|
||
void operator delete(void*) noexcept;void operator delete(void*, std::size_t) noexcept;void operator delete(void*, std::align_val_t) noexcept;void operator delete(void*, std::size_t, std::align_val_t) noexcept;
|
||
|
||
void* operator new[](std::size_t);void* operator new[](std::size_t, std::align_val_t);
|
||
|
||
void operator delete[](void*) noexcept;void operator delete[](void*, std::size_t) noexcept;void operator delete[](void*, std::align_val_t) noexcept;void operator delete[](void*, std::size_t, std::align_val_t) noexcept;
|
||
|
||
These implicit declarations introduce only the function namesoperator new,operator new[],operator delete, andoperator delete[][.](#dynamic.general-2.sentence-4)
|
||
|
||
[*Note [2](#dynamic.general-note-2)*:
|
||
|
||
The implicit declarations do not introduce
|
||
the names std,std::size_t,std::align_val_t,
|
||
or any other names that the library uses to
|
||
declare these names[.](#dynamic.general-2.sentence-5)
|
||
|
||
Thus, a [*new-expression*](expr.new#nt:new-expression "7.6.2.8 New [expr.new]"),[*delete-expression*](expr.delete#nt:delete-expression "7.6.2.9 Delete [expr.delete]"), or function call that refers to one of
|
||
these functions without importing or including the header [<new>](support.dynamic.general#header:%3cnew%3e "17.6.1 General [support.dynamic.general]") or importing a C++ library module ([[std.modules]](std.modules "16.4.2.4 Modules"))
|
||
is well-formed[.](#dynamic.general-2.sentence-6)
|
||
|
||
However, referring to std or std::size_t or std::align_val_t is ill-formed unless
|
||
a standard library declaration ([[cstddef.syn]](cstddef.syn "17.2.1 Header <cstddef> synopsis"), [[new.syn]](new.syn "17.6.2 Header <new> synopsis"), [[std.modules]](std.modules "16.4.2.4 Modules"))
|
||
of that name precedes ([[basic.lookup.general]](basic.lookup.general "6.5.1 General")) the use of that name[.](#dynamic.general-2.sentence-7)
|
||
|
||
â *end note*]
|
||
|
||
Allocation and/or
|
||
deallocation functions may also be declared and defined for any
|
||
class ([[class.free]](class.free "11.4.11 Allocation and deallocation functions"))[.](#dynamic.general-2.sentence-8)
|
||
|
||
[3](#dynamic.general-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4433)
|
||
|
||
If the behavior of an allocation or deallocation function
|
||
does not satisfy the semantic constraints
|
||
specified in [[basic.stc.dynamic.allocation]](#dynamic.allocation "6.8.6.5.2 Allocation functions") and [[basic.stc.dynamic.deallocation]](#dynamic.deallocation "6.8.6.5.3 Deallocation functions"),
|
||
the behavior is undefined[.](#dynamic.general-3.sentence-1)
|
||
|
||
#### [6.8.6.5.2](#dynamic.allocation) Allocation functions [[basic.stc.dynamic.allocation]](basic.stc.dynamic.allocation)
|
||
|
||
[1](#dynamic.allocation-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4444)
|
||
|
||
An allocation function that is not a class member function
|
||
shall belong to the global scope and not have a name with internal linkage[.](#dynamic.allocation-1.sentence-1)
|
||
|
||
The return type shall be void*[.](#dynamic.allocation-1.sentence-2)
|
||
|
||
The first
|
||
parameter shall have type std::size_t ([[support.types]](support.types "17.2 Common definitions"))[.](#dynamic.allocation-1.sentence-3)
|
||
|
||
The
|
||
first parameter shall not have an associated default
|
||
argument ([[dcl.fct.default]](dcl.fct.default "9.3.4.7 Default arguments"))[.](#dynamic.allocation-1.sentence-4)
|
||
|
||
The value of the first parameter
|
||
is interpreted as the requested size of the allocation[.](#dynamic.allocation-1.sentence-5)
|
||
|
||
An allocation
|
||
function can be a function template[.](#dynamic.allocation-1.sentence-6)
|
||
|
||
Such a template shall declare its
|
||
return type and first parameter as specified above (that is, template
|
||
parameter types shall not be used in the return type and first parameter
|
||
type)[.](#dynamic.allocation-1.sentence-7)
|
||
|
||
Allocation function templates shall have two or more parameters[.](#dynamic.allocation-1.sentence-8)
|
||
|
||
[2](#dynamic.allocation-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4458)
|
||
|
||
An allocation function attempts to allocate the requested amount of
|
||
storage[.](#dynamic.allocation-2.sentence-1)
|
||
|
||
If it is successful, it returns the address of the start
|
||
of a block of storage whose length in bytes is at least as large
|
||
as the requested size[.](#dynamic.allocation-2.sentence-2)
|
||
|
||
The order,
|
||
contiguity, and initial value of storage allocated by successive calls
|
||
to an allocation function are unspecified[.](#dynamic.allocation-2.sentence-3)
|
||
|
||
Even if the size of the space
|
||
requested is zero, the request can fail[.](#dynamic.allocation-2.sentence-4)
|
||
|
||
If the request succeeds, the
|
||
value returned by a replaceable allocation function
|
||
is a non-null pointer value ([[basic.compound]](basic.compound "6.9.4 Compound types"))p0 different from any previously returned value p1,
|
||
unless that value p1 was subsequently passed to a
|
||
replaceable deallocation function[.](#dynamic.allocation-2.sentence-5)
|
||
|
||
Furthermore, for the library allocation functions
|
||
in [[new.delete.single]](new.delete.single "17.6.3.2 Single-object forms") and [[new.delete.array]](new.delete.array "17.6.3.3 Array forms"),p0 represents the address of a block of storage disjoint from the storage
|
||
for any other object accessible to the caller[.](#dynamic.allocation-2.sentence-6)
|
||
|
||
The effect of indirecting through a pointer
|
||
returned from a request for zero size is undefined[.](#dynamic.allocation-2.sentence-7)[23](#footnote-23 "The intent is to have operator new() implementable by calling std::malloc() or std::calloc(), so the rules are substantially the same. C++ differs from C in requiring a zero request to return a non-null pointer.")
|
||
|
||
[3](#dynamic.allocation-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4487)
|
||
|
||
For an allocation function other than
|
||
a reserved placement allocation function ([[new.delete.placement]](new.delete.placement "17.6.3.4 Non-allocating forms")),
|
||
the pointer returned on a successful call
|
||
shall represent the address of storage that is aligned as follows:
|
||
|
||
- [(3.1)](#dynamic.allocation-3.1)
|
||
|
||
If the allocation function takes an argument
|
||
of type std::align_val_t,
|
||
the storage will have the alignment specified
|
||
by the value of this argument[.](#dynamic.allocation-3.1.sentence-1)
|
||
|
||
- [(3.2)](#dynamic.allocation-3.2)
|
||
|
||
Otherwise, if the allocation function is named operator new[],
|
||
the storage is aligned for any object that
|
||
does not have new-extended alignment ([[basic.align]](basic.align "6.8.3 Alignment")) and
|
||
is no larger than the requested size[.](#dynamic.allocation-3.2.sentence-1)
|
||
|
||
- [(3.3)](#dynamic.allocation-3.3)
|
||
|
||
Otherwise, the storage is aligned for any object that
|
||
does not have new-extended alignment and is of the requested size[.](#dynamic.allocation-3.3.sentence-1)
|
||
|
||
[4](#dynamic.allocation-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4508)
|
||
|
||
An allocation function that fails to allocate storage can invoke the
|
||
currently installed new-handler function ([[new.handler]](new.handler "17.6.4.3 Type new_handler")), if any[.](#dynamic.allocation-4.sentence-1)
|
||
|
||
[*Note [1](#dynamic.allocation-note-1)*:
|
||
|
||
A program-supplied allocation function can obtain the
|
||
currently installed new_handler using thestd::get_new_handler function ([[get.new.handler]](get.new.handler "17.6.4.5 get_new_handler"))[.](#dynamic.allocation-4.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
An allocation function that has a non-throwing
|
||
exception specification ([[except.spec]](except.spec "14.5 Exception specifications"))
|
||
indicates failure by returning
|
||
a null pointer value[.](#dynamic.allocation-4.sentence-3)
|
||
|
||
Any other allocation function
|
||
never returns a null pointer value and
|
||
indicates failure only by throwing an exception ([[except.throw]](except.throw "14.2 Throwing an exception")) of a type
|
||
that would match a handler ([[except.handle]](except.handle "14.4 Handling an exception")) of typestd::bad_alloc ([[bad.alloc]](bad.alloc "17.6.4.1 Class bad_alloc"))[.](#dynamic.allocation-4.sentence-4)
|
||
|
||
[5](#dynamic.allocation-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4527)
|
||
|
||
A global allocation function is only called as the result of a [new
|
||
expression](expr.new "7.6.2.8 New [expr.new]"), or called directly using the [function call](expr.call "7.6.1.3 Function call [expr.call]") syntax, or called indirectly to allocate storage for
|
||
a coroutine state ([[dcl.fct.def.coroutine]](dcl.fct.def.coroutine "9.6.4 Coroutine definitions")),
|
||
or called indirectly through calls to the
|
||
functions in the C++ standard library[.](#dynamic.allocation-5.sentence-1)
|
||
|
||
[*Note [2](#dynamic.allocation-note-2)*:
|
||
|
||
In particular, a
|
||
global allocation function is not called to allocate storage
|
||
for objects with static storage duration ([[basic.stc.static]](#static "6.8.6.2 Static storage duration")),
|
||
for objects or references with thread storage duration ([[basic.stc.thread]](#thread "6.8.6.3 Thread storage duration")),
|
||
for objects of type std::type_info ([[expr.typeid]](expr.typeid "7.6.1.8 Type identification")),
|
||
for an object of type std::contracts::contract_violation when a contract violation occurs ([[basic.contract.eval]](basic.contract.eval "6.11.2 Evaluation")), or
|
||
for an exception object ([[except.throw]](except.throw "14.2 Throwing an exception"))[.](#dynamic.allocation-5.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[23)](#footnote-23)[23)](#footnoteref-23)
|
||
|
||
The intent is
|
||
to have operator new() implementable by
|
||
calling std::malloc() or std::calloc(), so the rules are
|
||
substantially the same[.](#footnote-23.sentence-1)
|
||
|
||
C++ differs from C in requiring a zero request
|
||
to return a non-null pointer[.](#footnote-23.sentence-2)
|
||
|
||
#### [6.8.6.5.3](#dynamic.deallocation) Deallocation functions [[basic.stc.dynamic.deallocation]](basic.stc.dynamic.deallocation)
|
||
|
||
[1](#dynamic.deallocation-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4547)
|
||
|
||
A deallocation function that is not a class member function
|
||
shall belong to the global scope and not have a name with internal linkage[.](#dynamic.deallocation-1.sentence-1)
|
||
|
||
[2](#dynamic.deallocation-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4552)
|
||
|
||
A deallocation function
|
||
is a [*destroying operator delete*](#def:operator_delete,destroying "6.8.6.5.3 Deallocation functions [basic.stc.dynamic.deallocation]") if it has at least two parameters
|
||
and its second parameter
|
||
is of type std::destroying_delete_t[.](#dynamic.deallocation-2.sentence-1)
|
||
|
||
A destroying operator delete
|
||
shall be a class member function named operator delete[.](#dynamic.deallocation-2.sentence-2)
|
||
|
||
[*Note [1](#dynamic.deallocation-note-1)*:
|
||
|
||
Array deletion cannot use a destroying operator delete[.](#dynamic.deallocation-2.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[3](#dynamic.deallocation-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4564)
|
||
|
||
Each deallocation function shall return void[.](#dynamic.deallocation-3.sentence-1)
|
||
|
||
If the function is a destroying operator delete
|
||
declared in class type C,
|
||
the type of its first parameter shall be C*;
|
||
otherwise, the type of its first
|
||
parameter shall be void*[.](#dynamic.deallocation-3.sentence-2)
|
||
|
||
A deallocation function may have more
|
||
than one parameter[.](#dynamic.deallocation-3.sentence-3)
|
||
|
||
A [*usual deallocation function*](#def:usual_deallocation_function "6.8.6.5.3 Deallocation functions [basic.stc.dynamic.deallocation]") is a deallocation function
|
||
whose parameters after the first are
|
||
|
||
- [(3.1)](#dynamic.deallocation-3.1)
|
||
|
||
optionally, a parameter of type std::destroying_delete_t, then
|
||
|
||
- [(3.2)](#dynamic.deallocation-3.2)
|
||
|
||
optionally, a parameter of type std::size_t,[24](#footnote-24 "The global operator delete(void*, std::size_t) precludes use of an allocation function void operator new(std::size_t, std::size_t) as a placement allocation function ([diff.cpp11.basic]).") then
|
||
|
||
- [(3.3)](#dynamic.deallocation-3.3)
|
||
|
||
optionally, a parameter of type std::align_val_t[.](#dynamic.deallocation-3.sentence-4)
|
||
|
||
A destroying operator delete shall be a usual deallocation function[.](#dynamic.deallocation-3.sentence-5)
|
||
|
||
A deallocation function may be an instance of a function
|
||
template[.](#dynamic.deallocation-3.sentence-6)
|
||
|
||
Neither the first parameter nor the return type shall depend
|
||
on a template parameter[.](#dynamic.deallocation-3.sentence-7)
|
||
|
||
A deallocation
|
||
function template shall have two or more function parameters[.](#dynamic.deallocation-3.sentence-8)
|
||
|
||
A template
|
||
instance is never a usual deallocation function, regardless of its
|
||
signature[.](#dynamic.deallocation-3.sentence-9)
|
||
|
||
[4](#dynamic.deallocation-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4600)
|
||
|
||
If a deallocation function terminates by throwing an exception, the behavior is undefined[.](#dynamic.deallocation-4.sentence-1)
|
||
|
||
The value of the first argument supplied to a deallocation function may
|
||
be a null pointer value; if so, and if the deallocation function is one
|
||
supplied in the standard library, the call has no effect[.](#dynamic.deallocation-4.sentence-2)
|
||
|
||
[5](#dynamic.deallocation-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4606)
|
||
|
||
If the argument given to a deallocation function in the standard library
|
||
is a pointer that is not the null pointer value ([[basic.compound]](basic.compound "6.9.4 Compound types")), the
|
||
deallocation function shall deallocate the storage referenced by the
|
||
pointer, ending the duration of the region of storage[.](#dynamic.deallocation-5.sentence-1)
|
||
|
||
[24)](#footnote-24)[24)](#footnoteref-24)
|
||
|
||
The global operator delete(void*, std::size_t) precludes use of an
|
||
allocation function void operator new(std::size_t, std::size_t) as a placement
|
||
allocation function ([[diff.cpp11.basic]](diff.cpp11.basic "C.5.3 [basic]: basics"))[.](#footnote-24.sentence-1)
|