From Jason Turner

[basic.life]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpxc5wnmde/{from.md → to.md} +47 -44
tmp/tmpxc5wnmde/{from.md → to.md} RENAMED
@@ -1,24 +1,24 @@
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]].
@@ -33,43 +33,44 @@ member subobjects. — *end note*]
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`
@@ -101,12 +102,12 @@ void B::mutate() {
101
 
102
  void g() {
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*]
@@ -141,11 +142,11 @@ 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₂.
@@ -174,21 +175,23 @@ c1 = c2; // well-defined
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*:
192
 
193
  ``` cpp
194
  class T { };
@@ -202,11 +205,11 @@ void h() {
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*:
@@ -228,9 +231,9 @@ void h() {
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
 
 
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
+ multidimensional) 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]], [[class.copy.ctor]], and [[class.copy.assign]], and
18
+ except as described in [[allocator.members]]. The lifetime of an object
19
+ *o* of type `T` ends 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]].
 
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 can differ from the behavior of an object whose lifetime has
41
+ started and not ended. [[class.base.init]] and  [[class.cdtor]] describe
42
+ the behavior of an object during its periods of construction and
43
+ destruction. — *end note*]
44
+
45
+ A program may end the lifetime of an object of class type without
46
+ invoking the destructor, by reusing or releasing the storage as
47
+ described above.
48
+
49
+ [*Note 3*: A *delete-expression* [[expr.delete]] invokes the destructor
50
+ prior to releasing the storage. *end note*]
51
+
52
+ In this case, the destructor is not implicitly invoked.
53
+
54
+ [*Note 4*: The correct behavior of a program often depends on the
55
+ destructor being invoked for each object of class type. — *end note*]
56
 
57
  Before the lifetime of an object has started but after the storage which
58
+ the object will occupy has been allocated[^8]
 
 
 
 
 
 
 
 
 
59
 
60
+ or, after the lifetime of an object has ended and before the storage
61
+ which the object occupied is reused or released, any pointer that
62
+ represents the address of the storage location where the object will be
63
+ or was located may be used but only in limited ways. For an object under
64
+ construction or destruction, see  [[class.cdtor]]. Otherwise, such a
65
+ pointer refers to allocated storage [[basic.stc.dynamic.allocation]],
66
+ and using the pointer as if the pointer were of type `void*` is
67
+ well-defined. Indirection through such a pointer is permitted but the
68
+ resulting lvalue may only be used in limited ways, as described below.
69
+ The program has undefined behavior if:
70
+
71
+ - the pointer is used as the operand of a *delete-expression*,
72
  - the pointer is used to access a non-static data member or call a
73
  non-static member function of the object, or
74
  - the pointer is implicitly converted [[conv.ptr]] to a pointer to a
75
  virtual base class, or
76
  - the pointer is used as the operand of a `static_cast`
 
102
 
103
  void g() {
104
  void* p = std::malloc(sizeof(D1) + sizeof(D2));
105
  B* pb = new (p) D1;
106
  pb->mutate();
107
+ *pb; // OK, pb points to valid memory
108
+ void* q = pb; // OK, pb points to valid memory
109
  pb->f(); // undefined behavior: lifetime of *pb has ended
110
  }
111
  ```
112
 
113
  — *end example*]
 
142
 
143
  - the storage that o₂ occupies exactly overlays the storage that o₁
144
  occupied, and
145
  - o₁ and o₂ are of the same type (ignoring the top-level cv-qualifiers),
146
  and
147
+ - o₁ is not a const, complete object, and
148
  - neither o₁ nor o₂ is a potentially-overlapping subobject
149
  [[intro.object]], and
150
  - either o₁ and o₂ are both complete objects, or o₁ and o₂ are direct
151
  subobjects of objects p₁ and p₂, respectively, and p₁ is transparently
152
  replaceable by p₂.
 
175
  c1.f(); // well-defined; c1 refers to a new object of type C
176
  ```
177
 
178
  — *end example*]
179
 
180
+ [*Note 5*: If these conditions are not met, a pointer to the new object
181
  can be obtained from a pointer that represents the address of its
182
  storage by calling `std::launder` [[ptr.launder]]. — *end note*]
183
 
184
  If a program ends the lifetime of an object of type `T` with static
185
  [[basic.stc.static]], thread [[basic.stc.thread]], or automatic
186
  [[basic.stc.auto]] storage duration and if `T` has a non-trivial
187
+ destructor,[^9]
188
+
189
+ and another object of the original type does not occupy that same
190
+ storage location when the implicit destructor call takes place, the
191
+ behavior of the program is undefined. This is true even if the block is
192
+ exited with an exception.
193
 
194
  [*Example 3*:
195
 
196
  ``` cpp
197
  class T { };
 
205
  } // undefined behavior at block exit
206
  ```
207
 
208
  — *end example*]
209
 
210
+ Creating a new object within the storage that a const, complete object
211
  with static, thread, or automatic storage duration occupies, or within
212
  the storage that such a const object used to occupy before its lifetime
213
  ended, results in undefined behavior.
214
 
215
  [*Example 4*:
 
231
  — *end example*]
232
 
233
  In this subclause, “before” and “after” refer to the “happens before”
234
  relation [[intro.multithread]].
235
 
236
+ [*Note 6*: Therefore, undefined behavior results if an object that is
237
  being constructed in one thread is referenced from another thread
238
  without adequate synchronization. — *end note*]
239