From Jason Turner

[class.temporary]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpvapjdiy8/{from.md → to.md} +132 -55
tmp/tmpvapjdiy8/{from.md → to.md} RENAMED
@@ -1,26 +1,24 @@
1
- ## Temporary objects <a id="class.temporary">[[class.temporary]]</a>
2
 
3
  Temporary objects are created
4
 
5
- - when a prvalue is materialized so that it can be used as a glvalue (
6
- [[conv.rval]]),
7
  - when needed by the implementation to pass or return an object of
8
  trivially-copyable type (see below), and
9
- - when throwing an exception ([[except.throw]]). \[*Note 1*: The
10
- lifetime of exception objects is described in 
11
- [[except.throw]]. — *end note*]
12
 
13
- Even when the creation of the temporary object is unevaluated (Clause 
14
- [[expr]]), all the semantic restrictions shall be respected as if the
15
- temporary object had been created and later destroyed.
16
 
17
- [*Note 2*: This includes accessibility (Clause  [[class.access]]) and
18
- whether it is deleted, for the constructor selected and for the
19
- destructor. However, in the special case of the operand of a
20
- *decltype-specifier* ([[expr.call]]), no temporary is introduced, so
21
- the foregoing does not apply to such a prvalue. — *end note*]
22
 
23
  The materialization of a temporary object is generally delayed as long
24
  as possible in order to avoid creating unnecessary temporary objects.
25
 
26
  [*Note 3*:
@@ -33,15 +31,15 @@ Temporary objects are materialized:
33
  - when performing member access on a class prvalue ([[expr.ref]],
34
  [[expr.mptr.oper]]),
35
  - when performing an array-to-pointer conversion or subscripting on an
36
  array prvalue ([[conv.array]], [[expr.sub]]),
37
  - when initializing an object of type `std::initializer_list<T>` from a
38
- *braced-init-list* ([[dcl.init.list]]),
39
  - for certain unevaluated operands ([[expr.typeid]], [[expr.sizeof]]),
40
  and
41
- - when a prvalue appears as a discarded-value expression (Clause 
42
- [[expr]]).
43
 
44
  — *end note*]
45
 
46
  [*Example 1*:
47
 
@@ -77,78 +75,157 @@ void h() {
77
  `X(2)` is constructed in the space used to hold `f()`’s argument and
78
  `Y(3)` is constructed in the space used to hold `g()`’s argument.
79
  Likewise, `f()`’s result is constructed directly in `b` and `g()`’s
80
  result is constructed directly in `c`. On the other hand, the expression
81
  `a = f(a)` requires a temporary for the result of `f(a)`, which is
82
- materialized so that the reference parameter of `A::operator=(const A&)`
83
  can bind to it.
84
 
85
  — *end example*]
86
 
87
  When an object of class type `X` is passed to or returned from a
88
- function, if each copy constructor, move constructor, and destructor of
89
- `X` is either trivial or deleted, and `X` has at least one non-deleted
90
- copy or move constructor, implementations are permitted to create a
91
  temporary object to hold the function parameter or result object. The
92
  temporary object is constructed from the function argument or return
93
  value, respectively, and the function’s parameter or return object is
94
- initialized as if by using the non-deleted trivial constructor to copy
95
- the temporary (even if that constructor is inaccessible or would not be
96
  selected by overload resolution to perform a copy or move of the
97
  object).
98
 
99
  [*Note 4*: This latitude is granted to allow objects of class type to
100
  be passed to or returned from functions in registers. — *end note*]
101
 
102
  When an implementation introduces a temporary object of a class that has
103
- a non-trivial constructor ([[class.ctor]], [[class.copy]]), it shall
104
- ensure that a constructor is called for the temporary object. Similarly,
105
- the destructor shall be called for a temporary with a non-trivial
106
- destructor ([[class.dtor]]). Temporary objects are destroyed as the
107
- last step in evaluating the full-expression ([[intro.execution]]) that
108
- (lexically) contains the point where they were created. This is true
109
- even if that evaluation ends in throwing an exception. The value
110
- computations and side effects of destroying a temporary object are
111
- associated only with the full-expression, not with any specific
112
- subexpression.
113
 
114
  There are three contexts in which temporaries are destroyed at a
115
  different point than the end of the full-expression. The first context
116
  is when a default constructor is called to initialize an element of an
117
- array with no corresponding initializer ([[dcl.init]]). The second
118
- context is when a copy constructor is called to copy an element of an
119
- array while the entire array is copied ([[expr.prim.lambda.capture]], 
120
- [[class.copy]]). In either case, if the constructor has one or more
121
  default arguments, the destruction of every temporary created in a
122
  default argument is sequenced before the construction of the next array
123
  element, if any.
124
 
125
- The third context is when a reference is bound to a temporary.[^1] The
126
- temporary to which the reference is bound or the temporary that is the
127
- complete object of a subobject to which the reference is bound persists
128
- for the lifetime of the reference except:
 
 
129
 
130
- - A temporary object bound to a reference parameter in a function call (
131
- [[expr.call]]) persists until the completion of the full-expression
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  containing the call.
 
 
 
 
133
  - The lifetime of a temporary bound to the returned value in a function
134
- return statement ([[stmt.return]]) is not extended; the temporary is
135
- destroyed at the end of the full-expression in the return statement.
136
- - A temporary bound to a reference in a *new-initializer* (
137
- [[expr.new]]) persists until the completion of the full-expression
138
- containing the *new-initializer*.
139
- \[*Example 2*:
 
140
  ``` cpp
141
  struct S { int mi; const std::pair<int,int>& mp; };
142
  S a { 1, {2,3} };
143
- S* p = new S{ 1, {2,3} }; // Creates dangling reference
144
  ```
145
 
146
  — *end example*]
147
- \[*Note 5*: This may introduce a dangling reference, and
148
- implementations are encouraged to issue a warning in such a
149
- case. — *end note*]
150
 
151
  The destruction of a temporary whose lifetime is not extended by being
152
  bound to a reference is sequenced before the destruction of every
153
  temporary which is constructed earlier in the same full-expression. If
154
  the lifetime of two or more temporaries to which references are bound
@@ -162,11 +239,11 @@ storage duration as the temporary and created before the temporary is
162
  created the temporary shall be destroyed before `obj1` is destroyed; if
163
  `obj2` is an object with the same storage duration as the temporary and
164
  created after the temporary is created the temporary shall be destroyed
165
  after `obj2` is destroyed.
166
 
167
- [*Example 3*:
168
 
169
  ``` cpp
170
  struct S {
171
  S();
172
  S(int);
@@ -176,11 +253,11 @@ struct S {
176
  S obj1;
177
  const S& cr = S(16)+S(23);
178
  S obj2;
179
  ```
180
 
181
- the expression `S(16) + S(23)` creates three temporaries: a first
182
  temporary `T1` to hold the result of the expression `S(16)`, a second
183
  temporary `T2` to hold the result of the expression `S(23)`, and a third
184
  temporary `T3` to hold the result of the addition of these two
185
  expressions. The temporary `T3` is then bound to the reference `cr`. It
186
  is unspecified whether `T1` or `T2` is created first. On an
 
1
+ ### Temporary objects <a id="class.temporary">[[class.temporary]]</a>
2
 
3
  Temporary objects are created
4
 
5
+ - when a prvalue is converted to an xvalue [[conv.rval]],
 
6
  - when needed by the implementation to pass or return an object of
7
  trivially-copyable type (see below), and
8
+ - when throwing an exception [[except.throw]]. \[*Note 1*: The lifetime
9
+ of exception objects is described in  [[except.throw]]. — *end note*]
 
10
 
11
+ Even when the creation of the temporary object is unevaluated
12
+ [[expr.prop]], all the semantic restrictions shall be respected as if
13
+ the temporary object had been created and later destroyed.
14
 
15
+ [*Note 2*: This includes accessibility [[class.access]] and whether it
16
+ is deleted, for the constructor selected and for the destructor.
17
+ However, in the special case of the operand of a *decltype-specifier*
18
+ [[expr.call]], no temporary is introduced, so the foregoing does not
19
+ apply to such a prvalue. — *end note*]
20
 
21
  The materialization of a temporary object is generally delayed as long
22
  as possible in order to avoid creating unnecessary temporary objects.
23
 
24
  [*Note 3*:
 
31
  - when performing member access on a class prvalue ([[expr.ref]],
32
  [[expr.mptr.oper]]),
33
  - when performing an array-to-pointer conversion or subscripting on an
34
  array prvalue ([[conv.array]], [[expr.sub]]),
35
  - when initializing an object of type `std::initializer_list<T>` from a
36
+ *braced-init-list* [[dcl.init.list]],
37
  - for certain unevaluated operands ([[expr.typeid]], [[expr.sizeof]]),
38
  and
39
+ - when a prvalue that has type other than cv `void` appears as a
40
+ discarded-value expression [[expr.prop]].
41
 
42
  — *end note*]
43
 
44
  [*Example 1*:
45
 
 
75
  `X(2)` is constructed in the space used to hold `f()`’s argument and
76
  `Y(3)` is constructed in the space used to hold `g()`’s argument.
77
  Likewise, `f()`’s result is constructed directly in `b` and `g()`’s
78
  result is constructed directly in `c`. On the other hand, the expression
79
  `a = f(a)` requires a temporary for the result of `f(a)`, which is
80
+ materialized so that the reference parameter of `X::operator=(const X&)`
81
  can bind to it.
82
 
83
  — *end example*]
84
 
85
  When an object of class type `X` is passed to or returned from a
86
+ function, if `X` has at least one eligible copy or move constructor
87
+ [[special]], each such constructor is trivial, and the destructor of `X`
88
+ is either trivial or deleted, implementations are permitted to create a
89
  temporary object to hold the function parameter or result object. The
90
  temporary object is constructed from the function argument or return
91
  value, respectively, and the function’s parameter or return object is
92
+ initialized as if by using the eligible trivial constructor to copy the
93
+ temporary (even if that constructor is inaccessible or would not be
94
  selected by overload resolution to perform a copy or move of the
95
  object).
96
 
97
  [*Note 4*: This latitude is granted to allow objects of class type to
98
  be passed to or returned from functions in registers. — *end note*]
99
 
100
  When an implementation introduces a temporary object of a class that has
101
+ a non-trivial constructor ([[class.default.ctor]],
102
+ [[class.copy.ctor]]), it shall ensure that a constructor is called for
103
+ the temporary object. Similarly, the destructor shall be called for a
104
+ temporary with a non-trivial destructor [[class.dtor]]. Temporary
105
+ objects are destroyed as the last step in evaluating the full-expression
106
+ [[intro.execution]] that (lexically) contains the point where they were
107
+ created. This is true even if that evaluation ends in throwing an
108
+ exception. The value computations and side effects of destroying a
109
+ temporary object are associated only with the full-expression, not with
110
+ any specific subexpression.
111
 
112
  There are three contexts in which temporaries are destroyed at a
113
  different point than the end of the full-expression. The first context
114
  is when a default constructor is called to initialize an element of an
115
+ array with no corresponding initializer [[dcl.init]]. The second context
116
+ is when a copy constructor is called to copy an element of an array
117
+ while the entire array is copied ([[expr.prim.lambda.capture]],
118
+ [[class.copy.ctor]]). In either case, if the constructor has one or more
119
  default arguments, the destruction of every temporary created in a
120
  default argument is sequenced before the construction of the next array
121
  element, if any.
122
 
123
+ The third context is when a reference is bound to a temporary
124
+ object.[^17] The temporary object to which the reference is bound or the
125
+ temporary object that is the complete object of a subobject to which the
126
+ reference is bound persists for the lifetime of the reference if the
127
+ glvalue to which the reference is bound was obtained through one of the
128
+ following:
129
 
130
+ - a temporary materialization conversion [[conv.rval]],
131
+ - `(` *expression* `)`, where *expression* is one of these expressions,
132
+ - subscripting [[expr.sub]] of an array operand, where that operand is
133
+ one of these expressions,
134
+ - a class member access [[expr.ref]] using the `.` operator where the
135
+ left operand is one of these expressions and the right operand
136
+ designates a non-static data member of non-reference type,
137
+ - a pointer-to-member operation [[expr.mptr.oper]] using the `.*`
138
+ operator where the left operand is one of these expressions and the
139
+ right operand is a pointer to data member of non-reference type,
140
+ - a
141
+ - `const_cast` [[expr.const.cast]],
142
+ - `static_cast` [[expr.static.cast]],
143
+ - `dynamic_cast` [[expr.dynamic.cast]], or
144
+ - `reinterpret_cast` [[expr.reinterpret.cast]]
145
+
146
+ converting, without a user-defined conversion, a glvalue operand that
147
+ is one of these expressions to a glvalue that refers to the object
148
+ designated by the operand, or to its complete object or a subobject
149
+ thereof,
150
+ - a conditional expression [[expr.cond]] that is a glvalue where the
151
+ second or third operand is one of these expressions, or
152
+ - a comma expression [[expr.comma]] that is a glvalue where the right
153
+ operand is one of these expressions.
154
+
155
+ [*Example 2*:
156
+
157
+ ``` cpp
158
+ template<typename T> using id = T;
159
+
160
+ int i = 1;
161
+ int&& a = id<int[3]>{1, 2, 3}[i]; // temporary array has same lifetime as a
162
+ const int& b = static_cast<const int&>(0); // temporary int has same lifetime as b
163
+ int&& c = cond ? id<int[3]>{1, 2, 3}[i] : static_cast<int&&>(0);
164
+ // exactly one of the two temporaries is lifetime-extended
165
+ ```
166
+
167
+ — *end example*]
168
+
169
+ [*Note 5*:
170
+
171
+ An explicit type conversion ([[expr.type.conv]], [[expr.cast]]) is
172
+ interpreted as a sequence of elementary casts, covered above.
173
+
174
+ [*Example 3*:
175
+
176
+ ``` cpp
177
+ const int& x = (const int&)1; // temporary for value 1 has same lifetime as x
178
+ ```
179
+
180
+ — *end example*]
181
+
182
+ — *end note*]
183
+
184
+ [*Note 6*:
185
+
186
+ If a temporary object has a reference member initialized by another
187
+ temporary object, lifetime extension applies recursively to such a
188
+ member’s initializer.
189
+
190
+ [*Example 4*:
191
+
192
+ ``` cpp
193
+ struct S {
194
+ const int& m;
195
+ };
196
+ const S& s = S{1}; // both S and int temporaries have lifetime of s
197
+ ```
198
+
199
+ — *end example*]
200
+
201
+ — *end note*]
202
+
203
+ The exceptions to this lifetime rule are:
204
+
205
+ - A temporary object bound to a reference parameter in a function call
206
+ [[expr.call]] persists until the completion of the full-expression
207
  containing the call.
208
+ - A temporary object bound to a reference element of an aggregate of
209
+ class type initialized from a parenthesized *expression-list*
210
+ [[dcl.init]] persists until the completion of the full-expression
211
+ containing the *expression-list*.
212
  - The lifetime of a temporary bound to the returned value in a function
213
+ `return` statement [[stmt.return]] is not extended; the temporary is
214
+ destroyed at the end of the full-expression in the `return` statement.
215
+ - A temporary bound to a reference in a *new-initializer* [[expr.new]]
216
+ persists until the completion of the full-expression containing the
217
+ *new-initializer*.
218
+ \[*Note 7*: This may introduce a dangling reference. — *end note*]
219
+ \[*Example 5*:
220
  ``` cpp
221
  struct S { int mi; const std::pair<int,int>& mp; };
222
  S a { 1, {2,3} };
223
+ S* p = new S{ 1, {2,3} }; // creates dangling reference
224
  ```
225
 
226
  — *end example*]
 
 
 
227
 
228
  The destruction of a temporary whose lifetime is not extended by being
229
  bound to a reference is sequenced before the destruction of every
230
  temporary which is constructed earlier in the same full-expression. If
231
  the lifetime of two or more temporaries to which references are bound
 
239
  created the temporary shall be destroyed before `obj1` is destroyed; if
240
  `obj2` is an object with the same storage duration as the temporary and
241
  created after the temporary is created the temporary shall be destroyed
242
  after `obj2` is destroyed.
243
 
244
+ [*Example 6*:
245
 
246
  ``` cpp
247
  struct S {
248
  S();
249
  S(int);
 
253
  S obj1;
254
  const S& cr = S(16)+S(23);
255
  S obj2;
256
  ```
257
 
258
+ The expression `S(16) + S(23)` creates three temporaries: a first
259
  temporary `T1` to hold the result of the expression `S(16)`, a second
260
  temporary `T2` to hold the result of the expression `S(23)`, and a third
261
  temporary `T3` to hold the result of the addition of these two
262
  expressions. The temporary `T3` is then bound to the reference `cr`. It
263
  is unspecified whether `T1` or `T2` is created first. On an