From Jason Turner

[intro.execution]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpvupw5e_z/{from.md → to.md} +60 -27
tmp/tmpvupw5e_z/{from.md → to.md} RENAMED
@@ -62,16 +62,18 @@ or *initializer* E are
62
  A *full-expression* is
63
 
64
  - an unevaluated operand [[expr.context]],
65
  - a *constant-expression* [[expr.const]],
66
  - an immediate invocation [[expr.const]],
67
- - an *init-declarator* [[dcl.decl]] or a *mem-initializer*
 
68
  [[class.base.init]], including the constituent expressions of the
69
  initializer,
70
  - an invocation of a destructor generated at the end of the lifetime of
71
  an object other than a temporary object [[class.temporary]] whose
72
- lifetime has not been extended, or
 
73
  - an expression that is not a subexpression of another expression and
74
  that is not otherwise part of a full-expression.
75
 
76
  If a language construct is defined to produce an implicit call of a
77
  function, a use of the language construct is considered to be an
@@ -98,11 +100,11 @@ S s1(1); // full-expression comprises call of S::S(int)
98
  void f() {
99
  S s2 = 2; // full-expression comprises call of S::S(int)
100
  if (S(3).v()) // full-expression includes lvalue-to-rvalue and int to bool conversions,
101
  // performed before temporary is deleted at end of full-expression
102
  { }
103
- bool b = noexcept(S()); // exception specification of destructor of S considered for noexcept
104
 
105
  // full-expression is destruction of s2 at end of block
106
  }
107
  struct B {
108
  B(S = S(0));
@@ -119,19 +121,20 @@ full-expression. For example, subexpressions involved in evaluating
119
  default arguments [[dcl.fct.default]] are considered to be created in
120
  the expression that calls the function, not the expression that defines
121
  the default argument. — *end note*]
122
 
123
  Reading an object designated by a `volatile` glvalue [[basic.lval]],
124
- modifying an object, calling a library I/O function, or calling a
125
- function that does any of those operations are all *side effects*, which
126
- are changes in the state of the execution environment. *Evaluation* of
127
- an expression (or a subexpression) in general includes both value
 
128
  computations (including determining the identity of an object for
129
  glvalue evaluation and fetching a value previously assigned to an object
130
  for prvalue evaluation) and initiation of side effects. When a call to a
131
  library I/O function returns or an access through a volatile glvalue is
132
- evaluated the side effect is considered complete, even though some
133
  external actions implied by the call (such as the I/O itself) or by the
134
  `volatile` access may not have completed yet.
135
 
136
  *Sequenced before* is an asymmetric, transitive, pair-wise relation
137
  between evaluations executed by a single thread [[intro.multithread]],
@@ -156,29 +159,43 @@ every value computation and every side effect associated with the
156
  expression *X* is sequenced before every value computation and every
157
  side effect associated with the expression *Y*.
158
 
159
  Every value computation and side effect associated with a
160
  full-expression is sequenced before every value computation and side
161
- effect associated with the next full-expression to be evaluated.[^22]
162
 
163
  Except where noted, evaluations of operands of individual operators and
164
  of subexpressions of individual expressions are unsequenced.
165
 
166
  [*Note 5*: In an expression that is evaluated more than once during the
167
  execution of a program, unsequenced and indeterminately sequenced
168
  evaluations of its subexpressions need not be performed consistently in
169
  different evaluations. — *end note*]
170
 
171
  The value computations of the operands of an operator are sequenced
172
- before the value computation of the result of the operator. If a side
173
- effect on a memory location [[intro.memory]] is unsequenced relative to
174
- either another side effect on the same memory location or a value
175
- computation using the value of any object in the same memory location,
176
- and they are not potentially concurrent [[intro.multithread]], the
177
- behavior is undefined.
178
-
179
- [*Note 6*: The next subclause imposes similar, but more complex
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
  restrictions on potentially concurrent computations. — *end note*]
181
 
182
  [*Example 3*:
183
 
184
  ``` cpp
@@ -186,24 +203,35 @@ void g(int i) {
186
  i = 7, i++, i++; // i becomes 9
187
 
188
  i = i++ + 1; // the value of i is incremented
189
  i = i++ + i; // undefined behavior
190
  i = i + 1; // the value of i is incremented
 
 
 
191
  }
192
  ```
193
 
194
  — *end example*]
195
 
196
- When invoking a function (whether or not the function is inline), every
197
- argument expression and the postfix expression designating the called
198
- function are sequenced before every expression or statement in the body
199
- of the called function. For each function invocation or evaluation of an
200
- *await-expression* *F*, each evaluation that does not occur within *F*
201
- but is evaluated on the same thread and as part of the same signal
202
- handler (if any) is either sequenced before all evaluations that occur
203
- within *F* or sequenced after all evaluations that occur within
204
- *F*;[^23]
 
 
 
 
 
 
 
 
205
 
206
  if *F* invokes or resumes a coroutine [[expr.await]], only evaluations
207
  subsequent to the previous suspension (if any) and prior to the next
208
  suspension (if any) are considered to occur within *F*.
209
 
@@ -222,9 +250,14 @@ regardless of the syntax of the expression that calls the function.
222
 
223
  If a signal handler is executed as a result of a call to the
224
  `std::raise` function, then the execution of the handler is sequenced
225
  after the invocation of the `std::raise` function and before its return.
226
 
227
- [*Note 7*: When a signal is received for another reason, the execution
228
  of the signal handler is usually unsequenced with respect to the rest of
229
  the program. — *end note*]
230
 
 
 
 
 
 
 
62
  A *full-expression* is
63
 
64
  - an unevaluated operand [[expr.context]],
65
  - a *constant-expression* [[expr.const]],
66
  - an immediate invocation [[expr.const]],
67
+ - an *init-declarator* [[dcl.decl]] (including such introduced by a
68
+ structured binding [[dcl.struct.bind]]) or a *mem-initializer*
69
  [[class.base.init]], including the constituent expressions of the
70
  initializer,
71
  - an invocation of a destructor generated at the end of the lifetime of
72
  an object other than a temporary object [[class.temporary]] whose
73
+ lifetime has not been extended,
74
+ - the predicate of a contract assertion [[basic.contract]], or
75
  - an expression that is not a subexpression of another expression and
76
  that is not otherwise part of a full-expression.
77
 
78
  If a language construct is defined to produce an implicit call of a
79
  function, a use of the language construct is considered to be an
 
100
  void f() {
101
  S s2 = 2; // full-expression comprises call of S::S(int)
102
  if (S(3).v()) // full-expression includes lvalue-to-rvalue and int to bool conversions,
103
  // performed before temporary is deleted at end of full-expression
104
  { }
105
+ bool b = noexcept(S(4)); // exception specification of destructor of S considered for noexcept
106
 
107
  // full-expression is destruction of s2 at end of block
108
  }
109
  struct B {
110
  B(S = S(0));
 
121
  default arguments [[dcl.fct.default]] are considered to be created in
122
  the expression that calls the function, not the expression that defines
123
  the default argument. — *end note*]
124
 
125
  Reading an object designated by a `volatile` glvalue [[basic.lval]],
126
+ modifying an object, producing an injected declaration [[expr.const]],
127
+ calling a library I/O function, or calling a function that does any of
128
+ those operations are all *side effects*, which are changes in the state
129
+ of the execution or translation environment. *Evaluation* of an
130
+ expression (or a subexpression) in general includes both value
131
  computations (including determining the identity of an object for
132
  glvalue evaluation and fetching a value previously assigned to an object
133
  for prvalue evaluation) and initiation of side effects. When a call to a
134
  library I/O function returns or an access through a volatile glvalue is
135
+ evaluated, the side effect is considered complete, even though some
136
  external actions implied by the call (such as the I/O itself) or by the
137
  `volatile` access may not have completed yet.
138
 
139
  *Sequenced before* is an asymmetric, transitive, pair-wise relation
140
  between evaluations executed by a single thread [[intro.multithread]],
 
159
  expression *X* is sequenced before every value computation and every
160
  side effect associated with the expression *Y*.
161
 
162
  Every value computation and side effect associated with a
163
  full-expression is sequenced before every value computation and side
164
+ effect associated with the next full-expression to be evaluated.[^21]
165
 
166
  Except where noted, evaluations of operands of individual operators and
167
  of subexpressions of individual expressions are unsequenced.
168
 
169
  [*Note 5*: In an expression that is evaluated more than once during the
170
  execution of a program, unsequenced and indeterminately sequenced
171
  evaluations of its subexpressions need not be performed consistently in
172
  different evaluations. — *end note*]
173
 
174
  The value computations of the operands of an operator are sequenced
175
+ before the value computation of the result of the operator. The behavior
176
+ is undefined if
177
+
178
+ - a side effect on a memory location [[intro.memory]] or
179
+ - starting or ending the lifetime of an object in a memory location
180
+
181
+ is unsequenced relative to
182
+
183
+ - another side effect on the same memory location,
184
+ - starting or ending the lifetime of an object occupying storage that
185
+ overlaps with the memory location, or
186
+ - a value computation using the value of any object in the same memory
187
+ location,
188
+
189
+ and the two evaluations are not potentially concurrent
190
+ [[intro.multithread]].
191
+
192
+ [*Note 6*: Starting the lifetime of an object in a memory location can
193
+ end the lifetime of objects in other memory locations
194
+ [[basic.life]]. — *end note*]
195
+
196
+ [*Note 7*: The next subclause imposes similar, but more complex
197
  restrictions on potentially concurrent computations. — *end note*]
198
 
199
  [*Example 3*:
200
 
201
  ``` cpp
 
203
  i = 7, i++, i++; // i becomes 9
204
 
205
  i = i++ + 1; // the value of i is incremented
206
  i = i++ + i; // undefined behavior
207
  i = i + 1; // the value of i is incremented
208
+
209
+ union U { int x, y; } u;
210
+ (u.x = 1, 0) + (u.y = 2, 0); // undefined behavior
211
  }
212
  ```
213
 
214
  — *end example*]
215
 
216
+ When invoking a function *f* (whether or not the function is inline),
217
+ every argument expression and the postfix expression designating *f* are
218
+ sequenced before every precondition assertion of *f*
219
+ [[dcl.contract.func]], which in turn are sequenced before every
220
+ expression or statement in the body of *f*, which in turn are sequenced
221
+ before every postcondition assertion of *f*.
222
+
223
+ For each
224
+
225
+ - function invocation,
226
+ - evaluation of an *await-expression* [[expr.await]], or
227
+ - evaluation of a *throw-expression* [[expr.throw]]
228
+
229
+ *F*, each evaluation that does not occur within *F* but is evaluated on
230
+ the same thread and as part of the same signal handler (if any) is
231
+ either sequenced before all evaluations that occur within *F* or
232
+ sequenced after all evaluations that occur within *F*;[^22]
233
 
234
  if *F* invokes or resumes a coroutine [[expr.await]], only evaluations
235
  subsequent to the previous suspension (if any) and prior to the next
236
  suspension (if any) are considered to occur within *F*.
237
 
 
250
 
251
  If a signal handler is executed as a result of a call to the
252
  `std::raise` function, then the execution of the handler is sequenced
253
  after the invocation of the `std::raise` function and before its return.
254
 
255
+ [*Note 8*: When a signal is received for another reason, the execution
256
  of the signal handler is usually unsequenced with respect to the rest of
257
  the program. — *end note*]
258
 
259
+ During the evaluation of an expression as a core constant expression
260
+ [[expr.const]], evaluations of operands of individual operators and of
261
+ subexpressions of individual expressions that are otherwise either
262
+ unsequenced or indeterminately sequenced are evaluated in lexical order.
263
+