tmp/tmpl4efa8et/{from.md → to.md}
RENAMED
|
@@ -1,90 +1,85 @@
|
|
| 1 |
-
##
|
| 2 |
|
| 3 |
The *lifetime* of an object or reference is a runtime property of the
|
| 4 |
-
object or reference.
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
[*Note 1*: Initialization by a trivial copy/move constructor is
|
| 10 |
-
non-vacuous initialization. — *end note*]
|
| 11 |
-
|
| 12 |
-
The lifetime of an object of type `T` begins when:
|
| 13 |
|
| 14 |
- storage with the proper alignment and size for type `T` is obtained,
|
| 15 |
and
|
| 16 |
-
-
|
| 17 |
-
|
| 18 |
|
| 19 |
except that if the object is a union member or subobject thereof, its
|
| 20 |
lifetime only begins if that union member is the initialized member in
|
| 21 |
the union ([[dcl.init.aggr]], [[class.base.init]]), or as described in
|
| 22 |
-
[[class.union]]
|
|
|
|
|
|
|
| 23 |
|
| 24 |
-
- if `T` is a class type
|
| 25 |
-
|
| 26 |
- the storage which the object occupies is released, or is reused by an
|
| 27 |
-
object that is not nested within *o*
|
| 28 |
|
| 29 |
The lifetime of a reference begins when its initialization is complete.
|
| 30 |
-
The lifetime of a reference ends as if it were a scalar object
|
|
|
|
| 31 |
|
| 32 |
-
[*Note
|
| 33 |
member subobjects. — *end note*]
|
| 34 |
|
| 35 |
The properties ascribed to objects and references throughout this
|
| 36 |
-
|
| 37 |
-
its lifetime.
|
| 38 |
|
| 39 |
-
[*Note
|
| 40 |
after its lifetime ends there are significant restrictions on the use of
|
| 41 |
the object, as described below, in [[class.base.init]] and in
|
| 42 |
[[class.cdtor]]. Also, the behavior of an object under construction and
|
| 43 |
destruction might not be the same as the behavior of an object whose
|
| 44 |
lifetime has started and not ended. [[class.base.init]] and
|
| 45 |
-
[[class.cdtor]] describe the behavior of
|
| 46 |
-
and destruction
|
| 47 |
|
| 48 |
A program may end the lifetime of any object by reusing the storage
|
| 49 |
-
which the object occupies or by explicitly calling
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
|
| 59 |
Before the lifetime of an object has started but after the storage which
|
| 60 |
-
the object will occupy has been allocated[^
|
| 61 |
an object has ended and before the storage which the object occupied is
|
| 62 |
reused or released, any pointer that represents the address of the
|
| 63 |
storage location where the object will be or was located may be used but
|
| 64 |
only in limited ways. For an object under construction or destruction,
|
| 65 |
see [[class.cdtor]]. Otherwise, such a pointer refers to allocated
|
| 66 |
-
storage
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
behavior if:
|
| 71 |
|
| 72 |
- the object will be or was of a class type with a non-trivial
|
| 73 |
destructor and the pointer is used as the operand of a
|
| 74 |
*delete-expression*,
|
| 75 |
- the pointer is used to access a non-static data member or call a
|
| 76 |
non-static member function of the object, or
|
| 77 |
-
- the pointer is implicitly converted
|
| 78 |
virtual base class, or
|
| 79 |
-
- the pointer is used as the operand of a `static_cast`
|
| 80 |
-
[[expr.static.cast]]
|
| 81 |
cv `void`, or to pointer to cv `void` and subsequently to pointer to
|
| 82 |
-
cv `char`, cv `unsigned char`, or cv `std::byte`
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
[[expr.dynamic.cast]]).
|
| 86 |
|
| 87 |
[*Example 1*:
|
| 88 |
|
| 89 |
``` cpp
|
| 90 |
#include <cstdlib>
|
|
@@ -108,11 +103,11 @@ void g() {
|
|
| 108 |
void* p = std::malloc(sizeof(D1) + sizeof(D2));
|
| 109 |
B* pb = new (p) D1;
|
| 110 |
pb->mutate();
|
| 111 |
*pb; // OK: pb points to valid memory
|
| 112 |
void* q = pb; // OK: pb points to valid memory
|
| 113 |
-
pb->f(); // undefined behavior
|
| 114 |
}
|
| 115 |
```
|
| 116 |
|
| 117 |
— *end example*]
|
| 118 |
|
|
@@ -120,41 +115,42 @@ Similarly, before the lifetime of an object has started but after the
|
|
| 120 |
storage which the object will occupy has been allocated or, after the
|
| 121 |
lifetime of an object has ended and before the storage which the object
|
| 122 |
occupied is reused or released, any glvalue that refers to the original
|
| 123 |
object may be used but only in limited ways. For an object under
|
| 124 |
construction or destruction, see [[class.cdtor]]. Otherwise, such a
|
| 125 |
-
glvalue refers to allocated storage
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
undefined behavior if:
|
| 129 |
|
| 130 |
- the glvalue is used to access the object, or
|
| 131 |
- the glvalue is used to call a non-static member function of the
|
| 132 |
object, or
|
| 133 |
-
- the glvalue is bound to a reference to a virtual base class
|
| 134 |
-
[[dcl.init.ref]]
|
| 135 |
-
- the glvalue is used as the operand of a `dynamic_cast`
|
| 136 |
-
[[expr.dynamic.cast]]
|
| 137 |
|
| 138 |
If, after the lifetime of an object has ended and before the storage
|
| 139 |
which the object occupied is reused or released, a new object is created
|
| 140 |
at the storage location which the original object occupied, a pointer
|
| 141 |
that pointed to the original object, a reference that referred to the
|
| 142 |
original object, or the name of the original object will automatically
|
| 143 |
refer to the new object and, once the lifetime of the new object has
|
| 144 |
-
started, can be used to manipulate the new object, if
|
|
|
|
|
|
|
| 145 |
|
| 146 |
-
- the storage
|
| 147 |
-
|
| 148 |
-
-
|
| 149 |
-
|
| 150 |
-
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
-
|
| 154 |
-
|
| 155 |
-
|
| 156 |
|
| 157 |
[*Example 2*:
|
| 158 |
|
| 159 |
``` cpp
|
| 160 |
struct C {
|
|
@@ -178,18 +174,18 @@ c1 = c2; // well-defined
|
|
| 178 |
c1.f(); // well-defined; c1 refers to a new object of type C
|
| 179 |
```
|
| 180 |
|
| 181 |
— *end example*]
|
| 182 |
|
| 183 |
-
[*Note
|
| 184 |
can be obtained from a pointer that represents the address of its
|
| 185 |
-
storage by calling `std::launder`
|
| 186 |
|
| 187 |
-
If a program ends the lifetime of an object of type `T` with static
|
| 188 |
-
[[basic.stc.static]]
|
| 189 |
-
[[basic.stc.auto]]
|
| 190 |
-
destructor,[^
|
| 191 |
type occupies that same storage location when the implicit destructor
|
| 192 |
call takes place; otherwise the behavior of the program is undefined.
|
| 193 |
This is true even if the block is exited with an exception.
|
| 194 |
|
| 195 |
[*Example 3*:
|
|
@@ -206,14 +202,14 @@ void h() {
|
|
| 206 |
} // undefined behavior at block exit
|
| 207 |
```
|
| 208 |
|
| 209 |
— *end example*]
|
| 210 |
|
| 211 |
-
Creating a new object within the storage that a
|
| 212 |
with static, thread, or automatic storage duration occupies, or within
|
| 213 |
-
the storage that such a
|
| 214 |
-
|
| 215 |
|
| 216 |
[*Example 4*:
|
| 217 |
|
| 218 |
``` cpp
|
| 219 |
struct B {
|
|
@@ -229,12 +225,12 @@ void h() {
|
|
| 229 |
}
|
| 230 |
```
|
| 231 |
|
| 232 |
— *end example*]
|
| 233 |
|
| 234 |
-
In this
|
| 235 |
-
relation
|
| 236 |
|
| 237 |
-
[*Note
|
| 238 |
being constructed in one thread is referenced from another thread
|
| 239 |
without adequate synchronization. — *end note*]
|
| 240 |
|
|
|
|
| 1 |
+
### Lifetime <a id="basic.life">[[basic.life]]</a>
|
| 2 |
|
| 3 |
The *lifetime* of an object or reference is a runtime property of the
|
| 4 |
+
object or reference. A variable is said to have *vacuous initialization*
|
| 5 |
+
if it is default-initialized and, if it is of class type or a (possibly
|
| 6 |
+
multi-dimensional) array thereof, that class type has a trivial default
|
| 7 |
+
constructor. The lifetime of an object of type `T` begins when:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
|
| 9 |
- storage with the proper alignment and size for type `T` is obtained,
|
| 10 |
and
|
| 11 |
+
- its initialization (if any) is complete (including vacuous
|
| 12 |
+
initialization) [[dcl.init]],
|
| 13 |
|
| 14 |
except that if the object is a union member or subobject thereof, its
|
| 15 |
lifetime only begins if that union member is the initialized member in
|
| 16 |
the union ([[dcl.init.aggr]], [[class.base.init]]), or as described in
|
| 17 |
+
[[class.union]] and [[class.copy.ctor]], and except as described in
|
| 18 |
+
[[allocator.members]]. The lifetime of an object *o* of type `T` ends
|
| 19 |
+
when:
|
| 20 |
|
| 21 |
+
- if `T` is a non-class type, the object is destroyed, or
|
| 22 |
+
- if `T` is a class type, the destructor call starts, or
|
| 23 |
- the storage which the object occupies is released, or is reused by an
|
| 24 |
+
object that is not nested within *o* [[intro.object]].
|
| 25 |
|
| 26 |
The lifetime of a reference begins when its initialization is complete.
|
| 27 |
+
The lifetime of a reference ends as if it were a scalar object requiring
|
| 28 |
+
storage.
|
| 29 |
|
| 30 |
+
[*Note 1*: [[class.base.init]] describes the lifetime of base and
|
| 31 |
member subobjects. — *end note*]
|
| 32 |
|
| 33 |
The properties ascribed to objects and references throughout this
|
| 34 |
+
document apply for a given object or reference only during its lifetime.
|
|
|
|
| 35 |
|
| 36 |
+
[*Note 2*: In particular, before the lifetime of an object starts and
|
| 37 |
after its lifetime ends there are significant restrictions on the use of
|
| 38 |
the object, as described below, in [[class.base.init]] and in
|
| 39 |
[[class.cdtor]]. Also, the behavior of an object under construction and
|
| 40 |
destruction might not be the same as the behavior of an object whose
|
| 41 |
lifetime has started and not ended. [[class.base.init]] and
|
| 42 |
+
[[class.cdtor]] describe the behavior of an object during its periods of
|
| 43 |
+
construction and destruction. — *end note*]
|
| 44 |
|
| 45 |
A program may end the lifetime of any object by reusing the storage
|
| 46 |
+
which the object occupies or by explicitly calling a destructor or
|
| 47 |
+
pseudo-destructor [[expr.prim.id.dtor]] for the object. For an object of
|
| 48 |
+
a class type, the program is not required to call the destructor
|
| 49 |
+
explicitly before the storage which the object occupies is reused or
|
| 50 |
+
released; however, if there is no explicit call to the destructor or if
|
| 51 |
+
a *delete-expression* [[expr.delete]] is not used to release the
|
| 52 |
+
storage, the destructor is not implicitly called and any program that
|
| 53 |
+
depends on the side effects produced by the destructor has undefined
|
| 54 |
+
behavior.
|
| 55 |
|
| 56 |
Before the lifetime of an object has started but after the storage which
|
| 57 |
+
the object will occupy has been allocated[^11] or, after the lifetime of
|
| 58 |
an object has ended and before the storage which the object occupied is
|
| 59 |
reused or released, any pointer that represents the address of the
|
| 60 |
storage location where the object will be or was located may be used but
|
| 61 |
only in limited ways. For an object under construction or destruction,
|
| 62 |
see [[class.cdtor]]. Otherwise, such a pointer refers to allocated
|
| 63 |
+
storage [[basic.stc.dynamic.allocation]], and using the pointer as if
|
| 64 |
+
the pointer were of type `void*` is well-defined. Indirection through
|
| 65 |
+
such a pointer is permitted but the resulting lvalue may only be used in
|
| 66 |
+
limited ways, as described below. The program has undefined behavior if:
|
|
|
|
| 67 |
|
| 68 |
- the object will be or was of a class type with a non-trivial
|
| 69 |
destructor and the pointer is used as the operand of a
|
| 70 |
*delete-expression*,
|
| 71 |
- the pointer is used to access a non-static data member or call a
|
| 72 |
non-static member function of the object, or
|
| 73 |
+
- the pointer is implicitly converted [[conv.ptr]] to a pointer to a
|
| 74 |
virtual base class, or
|
| 75 |
+
- the pointer is used as the operand of a `static_cast`
|
| 76 |
+
[[expr.static.cast]], except when the conversion is to pointer to
|
| 77 |
cv `void`, or to pointer to cv `void` and subsequently to pointer to
|
| 78 |
+
cv `char`, cv `unsigned char`, or cv `std::byte` [[cstddef.syn]], or
|
| 79 |
+
- the pointer is used as the operand of a `dynamic_cast`
|
| 80 |
+
[[expr.dynamic.cast]].
|
|
|
|
| 81 |
|
| 82 |
[*Example 1*:
|
| 83 |
|
| 84 |
``` cpp
|
| 85 |
#include <cstdlib>
|
|
|
|
| 103 |
void* p = std::malloc(sizeof(D1) + sizeof(D2));
|
| 104 |
B* pb = new (p) D1;
|
| 105 |
pb->mutate();
|
| 106 |
*pb; // OK: pb points to valid memory
|
| 107 |
void* q = pb; // OK: pb points to valid memory
|
| 108 |
+
pb->f(); // undefined behavior: lifetime of *pb has ended
|
| 109 |
}
|
| 110 |
```
|
| 111 |
|
| 112 |
— *end example*]
|
| 113 |
|
|
|
|
| 115 |
storage which the object will occupy has been allocated or, after the
|
| 116 |
lifetime of an object has ended and before the storage which the object
|
| 117 |
occupied is reused or released, any glvalue that refers to the original
|
| 118 |
object may be used but only in limited ways. For an object under
|
| 119 |
construction or destruction, see [[class.cdtor]]. Otherwise, such a
|
| 120 |
+
glvalue refers to allocated storage [[basic.stc.dynamic.allocation]],
|
| 121 |
+
and using the properties of the glvalue that do not depend on its value
|
| 122 |
+
is well-defined. The program has undefined behavior if:
|
|
|
|
| 123 |
|
| 124 |
- the glvalue is used to access the object, or
|
| 125 |
- the glvalue is used to call a non-static member function of the
|
| 126 |
object, or
|
| 127 |
+
- the glvalue is bound to a reference to a virtual base class
|
| 128 |
+
[[dcl.init.ref]], or
|
| 129 |
+
- the glvalue is used as the operand of a `dynamic_cast`
|
| 130 |
+
[[expr.dynamic.cast]] or as the operand of `typeid`.
|
| 131 |
|
| 132 |
If, after the lifetime of an object has ended and before the storage
|
| 133 |
which the object occupied is reused or released, a new object is created
|
| 134 |
at the storage location which the original object occupied, a pointer
|
| 135 |
that pointed to the original object, a reference that referred to the
|
| 136 |
original object, or the name of the original object will automatically
|
| 137 |
refer to the new object and, once the lifetime of the new object has
|
| 138 |
+
started, can be used to manipulate the new object, if the original
|
| 139 |
+
object is transparently replaceable (see below) by the new object. An
|
| 140 |
+
object o₁ is *transparently replaceable* by an object o₂ if:
|
| 141 |
|
| 142 |
+
- the storage that o₂ occupies exactly overlays the storage that o₁
|
| 143 |
+
occupied, and
|
| 144 |
+
- o₁ and o₂ are of the same type (ignoring the top-level cv-qualifiers),
|
| 145 |
+
and
|
| 146 |
+
- o₁ is not a complete const object, and
|
| 147 |
+
- neither o₁ nor o₂ is a potentially-overlapping subobject
|
| 148 |
+
[[intro.object]], and
|
| 149 |
+
- either o₁ and o₂ are both complete objects, or o₁ and o₂ are direct
|
| 150 |
+
subobjects of objects p₁ and p₂, respectively, and p₁ is transparently
|
| 151 |
+
replaceable by p₂.
|
| 152 |
|
| 153 |
[*Example 2*:
|
| 154 |
|
| 155 |
``` cpp
|
| 156 |
struct C {
|
|
|
|
| 174 |
c1.f(); // well-defined; c1 refers to a new object of type C
|
| 175 |
```
|
| 176 |
|
| 177 |
— *end example*]
|
| 178 |
|
| 179 |
+
[*Note 3*: If these conditions are not met, a pointer to the new object
|
| 180 |
can be obtained from a pointer that represents the address of its
|
| 181 |
+
storage by calling `std::launder` [[ptr.launder]]. — *end note*]
|
| 182 |
|
| 183 |
+
If a program ends the lifetime of an object of type `T` with static
|
| 184 |
+
[[basic.stc.static]], thread [[basic.stc.thread]], or automatic
|
| 185 |
+
[[basic.stc.auto]] storage duration and if `T` has a non-trivial
|
| 186 |
+
destructor,[^12] the program must ensure that an object of the original
|
| 187 |
type occupies that same storage location when the implicit destructor
|
| 188 |
call takes place; otherwise the behavior of the program is undefined.
|
| 189 |
This is true even if the block is exited with an exception.
|
| 190 |
|
| 191 |
[*Example 3*:
|
|
|
|
| 202 |
} // undefined behavior at block exit
|
| 203 |
```
|
| 204 |
|
| 205 |
— *end example*]
|
| 206 |
|
| 207 |
+
Creating a new object within the storage that a const complete object
|
| 208 |
with static, thread, or automatic storage duration occupies, or within
|
| 209 |
+
the storage that such a const object used to occupy before its lifetime
|
| 210 |
+
ended, results in undefined behavior.
|
| 211 |
|
| 212 |
[*Example 4*:
|
| 213 |
|
| 214 |
``` cpp
|
| 215 |
struct B {
|
|
|
|
| 225 |
}
|
| 226 |
```
|
| 227 |
|
| 228 |
— *end example*]
|
| 229 |
|
| 230 |
+
In this subclause, “before” and “after” refer to the “happens before”
|
| 231 |
+
relation [[intro.multithread]].
|
| 232 |
|
| 233 |
+
[*Note 4*: Therefore, undefined behavior results if an object that is
|
| 234 |
being constructed in one thread is referenced from another thread
|
| 235 |
without adequate synchronization. — *end note*]
|
| 236 |
|