[basic.stc] (original) (raw)

6 Basics [basic]

6.7 Memory and objects [basic.memobj]

6.7.6 Storage duration [basic.stc]

6.7.6.1 General [basic.stc.general]

The storage duration is the property of an object that defines the minimum potential lifetime of the storage containing the object.

The storage duration is determined by the construct used to create the object and is one of the following:

[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]).

— _end note_]

Static, thread, and automatic storage durations are associated with objects introduced by declarations ([basic.def]) and with temporary objects ([class.temporary]).

The storage duration categories apply to references as well.

The storage duration of subobjects and reference members is that of their complete object ([intro.object]).

6.7.6.2 Static storage duration [basic.stc.static]

All variables which

have static storage duration.

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].

[Note 1:

The keyword static can be used to declare a block variable ([basic.scope.block]) with static storage duration;[stmt.dcl] and [basic.start.term] describe the initialization and destruction of such variables.

The keyword static applied to a class data member in a class definition gives the data member static storage duration ([class.static.data]).

— _end note_]

6.7.6.3 Thread storage duration [basic.stc.thread]

All variables declared with the thread_local keyword havethread storage duration.

The storage for these entities lasts for the duration of the thread in which they are created.

There is a distinct object or reference per thread, and use of the declared name refers to the entity associated with the current thread.

6.7.6.4 Automatic storage duration [basic.stc.auto]

Variables that belong to a block scope and are not explicitly declared static, thread_local, or extern haveautomatic storage duration.

The storage for such variables lasts until the block in which they are created exits.

[Note 1:

These variables are initialized and destroyed as described in [stmt.dcl].

— _end note_]

Variables that belong to a parameter scope also have automatic storage duration.

The storage for a function parameter lasts until immediately after its destruction ([expr.call]).

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].

6.7.6.5 Dynamic storage duration [basic.stc.dynamic]

6.7.6.5.1 General [basic.stc.dynamic.general]

A C++ implementation provides access to, and management of, dynamic storage via the global allocation functions operator new andoperator new[] and the global deallocation functions operator delete andoperator delete[].

[Note 1:

The non-allocating forms described in [new.delete.placement]do not perform allocation or deallocation.

— _end note_]

The library provides default definitions for the global allocation and deallocation functions.

Some global allocation and deallocation functions are replaceable ([dcl.fct.def.replace]).

The following allocation and deallocation functions ([support.dynamic]) are implicitly declared in global scope in each translation unit of a program.

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[].

[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.

Thus, a new-expression,delete-expression, or function call that refers to one of these functions without importing or including the header or importing a C++ library module ([std.modules]) is well-formed.

— _end note_]

Allocation and/or deallocation functions may also be declared and defined for any class ([class.free]).

If the behavior of an allocation or deallocation function does not satisfy the semantic constraints specified in [basic.stc.dynamic.allocation]and [basic.stc.dynamic.deallocation], the behavior is undefined.

6.7.6.5.2 Allocation functions [basic.stc.dynamic.allocation]

An allocation function that is not a class member function shall belong to the global scope and not have a name with internal linkage.

The return type shall be void*.

The first parameter shall have type std​::​size_t ([support.types]).

The first parameter shall not have an associated default argument ([dcl.fct.default]).

The value of the first parameter is interpreted as the requested size of the allocation.

An allocation function can be a function template.

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).

Allocation function templates shall have two or more parameters.

An allocation function attempts to allocate the requested amount of storage.

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.

The order, contiguity, and initial value of storage allocated by successive calls to an allocation function are unspecified.

Even if the size of the space requested is zero, the request can fail.

If the request succeeds, the value returned by a replaceable allocation function is a non-null pointer value ([basic.compound])p0 different from any previously returned value p1, unless that value p1 was subsequently passed to a replaceable deallocation function.

Furthermore, for the library allocation functions in [new.delete.single] and [new.delete.array],p0 represents the address of a block of storage disjoint from the storage for any other object accessible to the caller.

The effect of indirecting through a pointer returned from a request for zero size is undefined.23

For an allocation function other than a reserved placement allocation function ([new.delete.placement]), the pointer returned on a successful call shall represent the address of storage that is aligned as follows:

An allocation function that fails to allocate storage can invoke the currently installed new-handler function ([new.handler]), if any.

[Note 1:

A program-supplied allocation function can obtain the currently installed new_handler using thestd​::​get_new_handler function ([get.new.handler]).

— _end note_]

An allocation function that has a non-throwing exception specification ([except.spec]) indicates failure by returning a null pointer value.

Any other allocation function never returns a null pointer value and indicates failure only by throwing an exception ([except.throw]) of a type that would match a handler ([except.handle]) of typestd​::​bad_alloc ([bad.alloc]).

A global allocation function is only called as the result of a new expression, or called directly using the function callsyntax, or called indirectly to allocate storage for a coroutine state ([dcl.fct.def.coroutine]), or called indirectly through calls to the functions in the C++ standard library.

[Note 2:

In particular, a global allocation function is not called to allocate storage for objects with static storage duration ([basic.stc.static]), for objects or references with thread storage duration ([basic.stc.thread]), for objects of type std​::​type_info ([expr.typeid]), for an object of type std​::​contracts​::​contract_violationwhen a contract violation occurs ([basic.contract.eval]), or for an exception object ([except.throw]).

— _end note_]

6.7.6.5.3 Deallocation functions [basic.stc.dynamic.deallocation]

A deallocation function that is not a class member function shall belong to the global scope and not have a name with internal linkage.

A deallocation function is a destroying operator deleteif it has at least two parameters and its second parameter is of type std​::​destroying_delete_t.

A destroying operator delete shall be a class member function named operator delete.

[Note 1:

Array deletion cannot use a destroying operator delete.

— _end note_]

Each deallocation function shall return void.

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*.

A deallocation function may have more than one parameter.

A usual deallocation function is a deallocation function whose parameters after the first are

A destroying operator delete shall be a usual deallocation function.

A deallocation function may be an instance of a function template.

Neither the first parameter nor the return type shall depend on a template parameter.

A deallocation function template shall have two or more function parameters.

A template instance is never a usual deallocation function, regardless of its signature.

If a deallocation function terminates by throwing an exception, the behavior is undefined.

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.

If the argument given to a deallocation function in the standard library is a pointer that is not the null pointer value ([basic.compound]), the deallocation function shall deallocate the storage referenced by the pointer, ending the duration of the region of storage.