cpp/language/lifetime

Every and  has a lifetime, which is a runtime property: for any object or reference, there is a point of execution of a program when its lifetime begins, and there is a moment when it ends.

The lifetime of an object begins when:
 * storage with the proper alignment and size for its type is obtained, and
 * its initialization (if any) is complete (including via no constructor or ), except that
 * if the object is a or subobject thereof, its lifetime only begins if that union member is the initialized member in the union, or it is made active,
 * if the object is nested in a union object, its lifetime may begin if the containing union object is assigned or constructed by a trivial special member function,
 * an array object's lifetime may also begin if it is allocated by std.

Some operations of implicit-lifetime types in given region of storage and start their lifetime. If a subobject of an implicitly created object is not of an implicit-lifetime type, its lifetime does not begin implicitly.

The lifetime of an object ends when:
 * if it is of a non-class type, the object is destroyed (maybe via a pseudo-destructor call), or
 * if it is of a class type, the call starts, or
 * the storage which the object occupies is released, or is reused by an object that is not nested within it.

Lifetime of an object is equal to or is nested within the lifetime of its storage, see.

The lifetime of a begins when its initialization is complete and ends as if it were a scalar object.

Note: the lifetime of the referred object may end before the end of the lifetime of the reference, which makes possible.

Lifetimes of non-static data members and base subobjects begin and end following.

Temporary object lifetime
Temporary objects are created in the following situations:

Also, temporary objects are created:


 * when

All temporary objects are destroyed as the last step in evaluating the that (lexically) contains the point where they were created, and if multiple temporary objects were created, they are destroyed in the order opposite to the order of creation. This is true even if that evaluation ends in throwing an exception.

There are the following exceptions from that:
 * The lifetime of a temporary object may be extended by binding to a const lvalue reference, see for details.
 * The lifetime of a temporary object created when evaluating the default arguments of a default or copy constructor used to initialize or copy an element of an array ends before the next element of the array begins initialization.

Storage reuse
A program is not required to call the destructor of an object to end its lifetime if the object is (be careful that the correct behavior of the program may depend on the destructor). However, if a program ends the lifetime of a non-trivially destructible object that is a variable explicitly, it must ensure that a new object of the same type is constructed in-place (e.g. via placement new) before the destructor may be called implicitly, i.e. due to scope exit or exception for automatic objects, due to thread exit for thread-local objects, or due to program exit for static objects; otherwise the behavior is undefined.

It is undefined behavior to reuse storage that is or was occupied by a const complete object of static, thread-local, or automatic storage duration because such objects may be stored in read-only memory.

If a new object is created at the address that was occupied by another object, then all pointers, references, and the name of the original object will automatically refer to the new object and, once the lifetime of the new object begins, can be used to manipulate the new object, but only if the original object is transparently replaceable by the new object.

Object is transparently replaceable by object  if:
 * the storage for exactly overlays the storage location which  occupied
 * is of the same type as (ignoring the top-level cv-qualifiers)
 * is not a complete const object
 * neither nor  is a base class subobject
 * either
 * and are both complete objects, or
 * and are direct subobjects of objects  and  respectively, and  is transparently replaceable by.

Similarly, if an object is created in the storage of a class member or array element, the created object is only a subobject (member or element) of the original object's containing object if:
 * the lifetime of the containing object has begun and not ended
 * the storage for the new object exactly overlays the storage of the original object
 * the new object is of the same type as the original object (ignoring cv-qualification).

Providing storage
As a special case, objects can be created in arrays of (in which case it is said that the array provides storage for the object) if
 * the lifetime of the array has begun and not ended
 * the storage for the new object fits entirely within the array
 * there is no array object that satisfies these constraints nested within the array.

If that portion of the array previously provided storage for another object, the lifetime of that object ends because its storage was reused, however the lifetime of the array itself does not end (its storage is not considered to have been reused).

Access outside of lifetime
Before the lifetime of an object has started but after the storage which the object will occupy has been allocated or, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, the behaviors of the following uses of the glvalue expression that identifies that object are undefined, unless the object is being constructed or destructed (separate set of rules applies):
 * 1) Lvalue to rvalue conversion (e.g. function call to a function that takes a value).
 * 2) Access to a non-static data member or a call to a non-static member function.
 * 3) Binding a reference to a virtual base class subobject.
 * 4)  or  expressions.

The above rules apply to pointers as well (binding a reference to virtual base is replaced by implicit conversion to a pointer to virtual base), with two additional rules:
 * 1)  of a pointer to storage without an object is only allowed when casting to (possibly cv-qualified).
 * 2) Pointers to storage without an object that were cast to possibly cv-qualified  can only be  to pointers to possibly cv-qualified, or possibly cv-qualified.

During construction and destruction it is generally allowed to call non-static member functions, access non-static data members, and use and. However, because the lifetime either has not begun yet (during construction) or has already ended (during destruction), only specific operations are allowed. For one restriction, see.