Order of evaluation
Order of evaluation of any part of any expression, including order of evaluation of function arguments is unspecified (with some exceptions listed below). The compiler can evaluate operands and other subexpressions in any order, and may choose another order when the same expression is evaluated again.
There is no concept of left-to-right or right-to-left evaluation in C++. This is not to be confused with left-to-right and right-to-left associativity of operators: the expression a() + b() + c() is parsed as (a() + b()) + c() due to left-to-right associativity of operator+, but c() may be evaluated first, last, or between a() or b() at runtime:
Possible output:
b c a c a b
Contents |
[edit] "Sequenced before" rules (since C++11)
[edit] Evaluation of Expressions
Evaluation of each expression includes:
- Value computations: calculation of the value that is returned by the expression. This may involve determination of the identity of the object (glvalue evaluation, e.g. if the expression returns a reference to some object) or reading the value previously assigned to an object (prvalue evaluation, e.g. if the expression returns a number, or some other value).
- Initiation of side effects: access (read or write) to an object designated by a volatile glvalue, modification (writing) to an object, calling a library I/O function, or calling a function that does any of those operations.
[edit] Ordering
Sequenced before is an asymmetric, transitive, pair-wise relationship between evaluations A
and B
within the same thread.
- If
A
is sequenced beforeB
(or, equivalently,B
is sequenced afterA
), then evaluation ofA
will be complete before evaluation ofB
begins. - If
A
is not sequenced beforeB
andB
is sequenced beforeA
, then evaluation ofB
will be complete before evaluation ofA
begins. - If
A
is not sequenced beforeB
andB
is not sequenced beforeA
, then two possibilities exist:- Evaluations of
A
andB
are unsequenced : they may be performed in any order and may overlap (within a single thread of execution, the compiler may interleave the CPU instructions that compriseA
andB
). - Evaluations of
A
and B are indeterminately sequenced : they may be performed in any order but may not overlap: eitherA
will be complete beforeB
, orB
will be complete beforeA
. The order may be the opposite the next time the same expression is evaluated.
- Evaluations of
An expression X is said to be sequenced before an expression Y if every value computation and every side effect associated with X is sequenced before every value computation and every side effect associated with the expression Y.
[edit] Rules
- every argument expression and the postfix expression designating func
|
(since C++26) |
- every expression or statement in the body of func
|
(since C++26) |
The rule 10 has one exception: function calls made by a standard library algorithm executing under std::execution::par_unseq execution policy are unsequenced and may be arbitrarily interleaved with each other. | (since C++17) |
13) In a function-call expression, the expression that names the function is sequenced before every argument expression and every default argument.
14) In a function call, value computations and side effects of the initialization of every parameter are indeterminately sequenced with respect to value computations and side effects of any other parameter.
15) Every overloaded operator obeys the sequencing rules of the built-in operator it overloads when called using operator notation.
16) In a subscript expression E1[E2], E1 is sequenced before E2.
17) In a pointer-to-member expression E1.*E2 or E1->*E2, E1 is sequenced before E2 (unless the dynamic type of E1 does not contain the member to which E2 refers).
18) In a shift operator expression E1 << E2 and E1 >> E2, E1 is sequenced before E2.
19) In every simple assignment expression E1 = E2 and every compound assignment expression E1 @= E2, E2 is sequenced before E1.
20) Every expression in a comma-separated list of expressions in a parenthesized initializer is evaluated as if for a function call (indeterminately-sequenced).
|
(since C++17) |
[edit] Undefined behavior
The behavior is undefined in the following cases: