Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      Order of evaluation

      From cppreference.com
      <cpp‎ |language
       
       
      C++ language
      General topics
      Flow control
      Conditional execution statements
      Iteration statements (loops)
      Jump statements
      Functions
      Function declaration
      Lambda function expression
      inline specifier
      Dynamic exception specifications(until C++17*)
      noexcept specifier(C++11)
      Exceptions
      Namespaces
      Types
      Specifiers
      constexpr(C++11)
      consteval(C++20)
      constinit(C++20)
      Storage duration specifiers
      Initialization
      Expressions
      Value categories
      Order of evaluation
      Alternative representations
      Literals
      Boolean -Integer -Floating-point
      Character -String -nullptr(C++11)
      User-defined(C++11)
      Utilities
      Attributes(C++11)
      Types
      typedef declaration
      Type alias declaration(C++11)
      Casts
      Memory allocation
      Classes
      Class-specific function properties
      Special member functions
      Templates
      Miscellaneous
       
      Expressions
      General
      Literals
      Operators
      Conversions
       

      Order of evaluation of any part of any expression, including order of evaluation of function arguments isunspecified (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 expressiona()+ b()+ c() is parsed as(a()+ b())+ c() due to left-to-right associativity ofoperator+, butc() may be evaluated first, last, or betweena() orb() at runtime:

      Run this code
      #include <cstdio> int a(){returnstd::puts("a");}int b(){returnstd::puts("b");}int c(){returnstd::puts("c");} void z(int,int,int){} int main(){    z(a(), b(), c());// all 6 permutations of output are allowedreturn a()+ b()+ c();// all 6 permutations of output are allowed}

      Possible output:

      bcaca 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 ofside 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 evaluationsA andB within the same thread.

      • IfA is sequenced beforeB (or, equivalently,B issequenced afterA), then evaluation ofA will be complete before evaluation ofB begins.
      • IfA is not sequenced beforeB andB is sequenced beforeA, then evaluation ofB will be complete before evaluation ofA begins.
      • IfA is not sequenced beforeB andB is not sequenced beforeA, then two possibilities exist:
        • Evaluations ofA andB areunsequenced : 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 ofA and B areindeterminately 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.

      An expressionX is said to besequenced before an expressionY if every value computation and every side effect associated withX is sequenced before every value computation and every side effect associated with the expressionY.

      [edit]Rules

      1) Eachfull-expression is sequenced before the next full-expression.
      2) The value computations (but not the side effects) of the operands to anyoperator are sequenced before the value computation of the result of the operator (but not its side effects).
      3) When calling a functionfunc (whether or not the function is inline, and whether or not explicit function call syntax is used), each item in the following list is sequenced before the next item:
      • every argument expression and the postfix expression designatingfunc
      (since C++26)
      • every expression or statement in the body offunc
      (since C++26)
      4) The value computation of the built-inpost-increment and post-decrement operators is sequenced before its side effect.
      5) The side effect of the built-inpre-increment and pre-decrement operators is sequenced before its value computation (implicit rule due to definition as compound assignment).
      6) The first (left) operand of the built-inlogical AND operator&&, the built-in logical OR operator|| and the built-incomma operator, is sequenced before the second (right) operand.
      7) The first operand in theconditional operator?: is sequenced before the second or third operand.
      8) The side effect (modification of the left argument) of the built-inassignment operator and of all built-incompound assignment operators is sequenced after the value computation (but not the side effects) of both left and right arguments, and is sequenced before the value computation of the assignment expression (that is, before returning the reference to the modified object).
      9) Inlist-initialization, every value computation and side effect of a given initializer clause is sequenced before every value computation and side effect associated with any initializer clause that follows it in the brace-enclosed comma-separated list of initializers.
      10) A function call that is not sequenced before or sequenced after another expression evaluation outside of the function (possibly another function call) is indeterminately sequenced with respect to that evaluation (the program must behaveas if the CPU instructions that constitute a function call were not interleaved with instructions constituting evaluations of other expressions, including other function calls, even if the function was inlined).
      The rule 10 has one exception: function calls made by a standard library algorithm executing understd::execution::par_unseq execution policy are unsequenced and may be arbitrarily interleaved with each other.(since C++17)
      11) The call to the allocation function (operator new) isindeterminately sequenced with respect to(until C++17)sequenced before(since C++17) the evaluation of the constructor arguments in anew expression.
      12) When returning from a function, copy-initialization of the temporary that is the result of evaluating the function call is sequenced before the destruction of all temporaries at the end of the operand of thereturn statement, which, in turn, is sequenced before the destruction of local variables of the block enclosing thereturn statement.
      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 expressionE1[E2],E1 is sequenced beforeE2.
      17) In a pointer-to-member expressionE1.*E2 orE1->*E2,E1 is sequenced beforeE2 (unless the dynamic type ofE1 does not contain the member to whichE2 refers).
      18) In a shift operator expressionE1<< E2 andE1>> E2,E1 is sequenced beforeE2.
      19) In every simple assignment expressionE1= E2 and every compound assignment expressionE1 @= E2,E2 is sequenced beforeE1.
      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 isundefined in the following cases:

      1) A side effect on amemory location is unsequenced relative to another side effect on the same memory location:
      i=++i+2;// well-definedi= i+++2;// undefined behavior until C++17f(i=-2, i=-2);// undefined behavior until C++17f(++i,++i);// undefined behavior until C++17, unspecified after C++17i=++i+ i++;// undefined behavior
      2) A side effect on a memory location is unsequenced relative to a value computation using the value of any object in the same memory location:
      cout<< i<< i++;// undefined behavior until C++17a[i]= i++;// undefined behavior until C++17n=++i+ i;// undefined behavior
      3) Starting or ending thelifetime of an object in a memory location is unsequenced relative to any of the following operations:
      • a side effect on the same memory location
      • a value computation using the value of any object in the same memory location
      • starting or ending the lifetime of an object occupying storage that overlaps with the memory location
      union U{int x, y;} u;(u.x=1,0)+(u.y=2,0);// undefined behavior

      [edit]Sequence point rules(until C++11)

      [edit]Pre-C++11 Definitions

      Evaluation of an expression might produce side effects, which are: accessing an object designated by a volatile lvalue, modifying an object, calling a library I/O function, or calling a function that does any of those operations.

      Asequence point is a point in the execution sequence where all side effects from the previous evaluations in the sequence are complete, and no side effects of the subsequent evaluations started.

      [edit]Pre-C++11 Rules

      1) There is a sequence point at the end of eachfull-expression (typically, at the semicolon).
      2) When calling a function (whether or not the function is inline and whether or not function call syntax was used), there is a sequence point after the evaluation of all function arguments (if any) which takes place before execution of any expressions or statements in the function body.
      3) When returning from a function, there is a sequence point after the copy-initialization of the result of the function call, and before the destruction of all temporary objects at the end ofexpression in thereturn statement (if any).
      4) There is a sequence point after the copying of a returned value of a function and before the execution of any expressions outside the function.
      5) Once the execution of a function begins, no expressions from the calling function are evaluated until execution of the called function has completed (functions cannot be interleaved).
      6) In the evaluation of each of the following four expressions, using the built-in (non-overloaded) operators, there is a sequence point after the evaluation of the expressiona.
      a&& ba|| ba? b: ca , b

      [edit]Pre-C++11 Undefined behavior

      The behavior isundefined in the following cases:

      1) Between the previous and next sequence point, the value of any object in a memory location is modified more than once by the evaluation of an expression:
      i=++i+ i++;// undefined behaviori= i+++1;// undefined behaviori=++i+1;// undefined behavior++++i;// undefined behaviorf(++i,++i);// undefined behaviorf(i=-1, i=-1);// undefined behavior
      2) Between the previous and next sequence point, for an object whose value is modified by the evaluation of an expression, its prior value is accessed in a way other than to determine the value to be stored:
      cout<< i<< i++;// undefined behaviora[i]= i++;// undefined behavior

      [edit]Defect reports

      The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

      DRApplied toBehavior as publishedCorrect behavior
      CWG 1885C++11sequencing of the destruction of automatic
      variables on function return was not explicit
      sequencing rules added
      CWG 1949C++11“sequenced after” was used but not defined in the C++ standarddefined as the inverse
      of “sequenced before”
      CWG 1953C++11side effects and value computations involving a memory
      location could be unsequenced relative to starting or ending
      the lifetime of an object in the same memory location
      the behavior is
      undefined in this case
      CWG 2146C++98the cases involving undefined behaviors did not consider bit-fieldsconsidered

      [edit]References

      • C++23 standard (ISO/IEC 14882:2024):
      • 6.9.1 Program execution [intro.execution]
      • 7.6.1.6 Increment and decrement [expr.post.incr]
      • 7.6.2.8 New [expr.new]
      • 7.6.14 Logical AND operator [expr.log.and]
      • 7.6.15 Logical OR operator [expr.log.or]
      • 7.6.16 Conditional operator [expr.cond]
      • 7.6.19 Assignment and compound assignment operators [expr.ass]
      • 7.6.20 Comma operator [expr.comma]
      • 9.4.5 List-initialization [dcl.init.list]
      • C++20 standard (ISO/IEC 14882:2020):
      • 6.9.1 Program execution [intro.execution]
      • 7.6.1.5 Increment and decrement [expr.post.incr]
      • 7.6.2.7 New [expr.new]
      • 7.6.14 Logical AND operator [expr.log.and]
      • 7.6.15 Logical OR operator [expr.log.or]
      • 7.6.16 Conditional operator [expr.cond]
      • 7.6.19 Assignment and compound assignment operators [expr.ass]
      • 7.6.20 Comma operator [expr.comma]
      • 9.4.4 List-initialization [dcl.init.list]
      • C++17 standard (ISO/IEC 14882:2017):
      • 4.6 Program execution [intro.execution]
      • 8.2.6 Increment and decrement [expr.post.incr]
      • 8.3.4 New [expr.new]
      • 8.14 Logical AND operator [expr.log.and]
      • 8.15 Logical OR operator [expr.log.or]
      • 8.16 Conditional operator [expr.cond]
      • 8.18 Assignment and compound assignment operators [expr.ass]
      • 8.19 Comma operator [expr.comma]
      • 11.6.4 List-initialization [dcl.init.list]
      • C++14 standard (ISO/IEC 14882:2014):
      • 1.9 Program execution [intro.execution]
      • 5.2.6 Increment and decrement [expr.post.incr]
      • 5.3.4 New [expr.new]
      • 5.14 Logical AND operator [expr.log.and]
      • 5.15 Logical OR operator [expr.log.or]
      • 5.16 Conditional operator [expr.cond]
      • 5.17 Assignment and compound assignment operators [expr.ass]
      • 5.18 Comma operator [expr.comma]
      • 8.5.4 List-initialization [dcl.init.list]
      • C++11 standard (ISO/IEC 14882:2011):
      • 1.9 Program execution [intro.execution]
      • 5.2.6 Increment and decrement [expr.post.incr]
      • 5.3.4 New [expr.new]
      • 5.14 Logical AND operator [expr.log.and]
      • 5.15 Logical OR operator [expr.log.or]
      • 5.16 Conditional operator [expr.cond]
      • 5.17 Assignment and compound assignment operators [expr.ass]
      • 5.18 Comma operator [expr.comma]
      • 8.5.4 List-initialization [dcl.init.list]

      [edit]See also

      • Operator precedence which defines how expressions are built from their source code representation.
      C documentation forOrder of evaluation
      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/language/eval_order&oldid=181353"

      [8]ページ先頭

      ©2009-2025 Movatter.jp