This commit is contained in:
2025-10-25 03:02:53 +03:00
commit 043225d523
3416 changed files with 681196 additions and 0 deletions

419
cppdraft/intro/execution.md Normal file
View File

@@ -0,0 +1,419 @@
[intro.execution]
# 6 Basics [[basic]](./#basic)
## 6.10 Program execution [[basic.exec]](basic.exec#intro.execution)
### 6.10.1 Sequential execution [intro.execution]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6225)
An instance of each object with [automatic storage
duration](basic.stc.auto "6.8.6.4Automatic storage duration[basic.stc.auto]") is associated with each entry into its
block[.](#1.sentence-1)
Such an object exists and retains its last-stored value during
the execution of the block and while the block is suspended (by a call
of a function, suspension of a coroutine ([[expr.await]](expr.await "7.6.2.4Await")), or receipt of a signal)[.](#1.sentence-2)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6232)
A [*constituent expression*](#def:constituent_expression "6.10.1Sequential execution[intro.execution]") is defined as follows:
- [(2.1)](#2.1)
The constituent expression of an expression is that expression[.](#2.1.sentence-1)
- [(2.2)](#2.2)
The constituent expression of a conversion is
the corresponding implicit function call, if any, or
the converted expression otherwise[.](#2.2.sentence-1)
- [(2.3)](#2.3)
The constituent expressions of a [*braced-init-list*](dcl.init.general#nt:braced-init-list "9.5.1General[dcl.init.general]") or
of a (possibly parenthesized) [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1General[expr.post.general]") are the constituent expressions of the elements of the respective list[.](#2.3.sentence-1)
- [(2.4)](#2.4)
The constituent expressions of a [*brace-or-equal-initializer*](dcl.init.general#nt:brace-or-equal-initializer "9.5.1General[dcl.init.general]") of the form = [*initializer-clause*](dcl.init.general#nt:initializer-clause "9.5.1General[dcl.init.general]") are the constituent expressions of the [*initializer-clause*](dcl.init.general#nt:initializer-clause "9.5.1General[dcl.init.general]")[.](#2.4.sentence-1)
[*Example [1](#example-1)*: struct A { int x; };struct B { int y; struct A a; };
B b = { 5, { 1+1 } };
The constituent expressions of the [*initializer*](dcl.init.general#nt:initializer "9.5.1General[dcl.init.general]") used for the initialization of b are 5 and 1+1[.](#2.sentence-2)
— *end example*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6260)
The [*immediate subexpressions*](#def:immediate_subexpression "6.10.1Sequential execution[intro.execution]") of an expression E are
- [(3.1)](#3.1)
the constituent expressions of E's operands ([[expr.prop]](expr.prop "7.2Properties of expressions")),
- [(3.2)](#3.2)
any function call that E implicitly invokes,
- [(3.3)](#3.3)
if E is a [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1General[expr.prim.lambda.general]") ([[expr.prim.lambda]](expr.prim.lambda "7.5.6Lambda expressions")),
the initialization of the entities captured by copy and
the constituent expressions of the [*initializer*](dcl.init.general#nt:initializer "9.5.1General[dcl.init.general]") of the [*init-capture*](expr.prim.lambda.capture#nt:init-capture "7.5.6.3Captures[expr.prim.lambda.capture]")*s*,
- [(3.4)](#3.4)
if E is a [function call](expr.call "7.6.1.3Function call[expr.call]") or implicitly invokes a function,
the constituent expressions of each default argument ([[dcl.fct.default]](dcl.fct.default "9.3.4.7Default arguments"))
used in the call, or
- [(3.5)](#3.5)
if E creates an aggregate object ([[dcl.init.aggr]](dcl.init.aggr "9.5.2Aggregates")),
the constituent expressions of each default member initializer ([[class.mem]](class.mem "11.4Class members"))
used in the initialization[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6281)
A [*subexpression*](#def:subexpression "6.10.1Sequential execution[intro.execution]") of an expression E is
an immediate subexpression of E or
a subexpression of an immediate subexpression of E[.](#4.sentence-1)
[*Note [1](#note-1)*:
Expressions appearing in the [*compound-statement*](stmt.block#nt:compound-statement "8.4Compound statement or block[stmt.block]") of a [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1General[expr.prim.lambda.general]") are not subexpressions of the [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1General[expr.prim.lambda.general]")[.](#4.sentence-2)
— *end note*]
The [*potentially-evaluated subexpressions*](#def:subexpression,potentially-evaluated "6.10.1Sequential execution[intro.execution]") of
an expression, conversion, or [*initializer*](dcl.init.general#nt:initializer "9.5.1General[dcl.init.general]") E are
- [(4.1)](#4.1)
the constituent expressions of E and
- [(4.2)](#4.2)
the subexpressions thereof that
are not subexpressions of a nested unevaluated operand ([[expr.context]](expr.context#term.unevaluated.operand "7.2.3Context dependence"))[.](#4.sentence-3)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6299)
A [*full-expression*](#def:full-expression "6.10.1Sequential execution[intro.execution]") is
- [(5.1)](#5.1)
an [unevaluated operand](expr.context#def:unevaluated_operand "7.2.3Context dependence[expr.context]"),
- [(5.2)](#5.2)
a [*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") ([[expr.const]](expr.const "7.7Constant expressions")),
- [(5.3)](#5.3)
an immediate invocation ([[expr.const]](expr.const "7.7Constant expressions")),
- [(5.4)](#5.4)
an [*init-declarator*](dcl.decl.general#nt:init-declarator "9.3.1General[dcl.decl.general]") ([[dcl.decl]](dcl.decl "9.3Declarators"))
(including such introduced by a structured binding ([[dcl.struct.bind]](dcl.struct.bind "9.7Structured binding declarations"))) or
a [*mem-initializer*](class.base.init#nt:mem-initializer "11.9.3Initializing bases and members[class.base.init]") ([[class.base.init]](class.base.init "11.9.3Initializing bases and members")),
including the constituent expressions of the initializer,
- [(5.5)](#5.5)
an invocation of a destructor generated at the end of the lifetime
of an object other than a temporary object ([[class.temporary]](class.temporary "6.8.7Temporary objects"))
whose lifetime has not been extended,
- [(5.6)](#5.6)
the predicate of a contract assertion ([[basic.contract]](basic.contract "6.11Contract assertions")), or
- [(5.7)](#5.7)
an expression that is not a subexpression of another expression and
that is not otherwise part of a full-expression[.](#5.sentence-1)
If a language construct is defined to produce an implicit call of a function,
a use of the language construct is considered to be an expression
for the purposes of this definition[.](#5.sentence-2)
Conversions applied to the result of an expression in order to satisfy the requirements
of the language construct in which the expression appears
are also considered to be part of the full-expression[.](#5.sentence-3)
For an initializer, performing the initialization of the entity
(including evaluating default member initializers of an aggregate)
is also considered part of the full-expression[.](#5.sentence-4)
[*Example [2](#example-2)*: struct S { S(int i): I(i) { } // full-expression is initialization of Iint& v() { return I; }~S() noexcept(false) { }private:int I;};
S s1(1); // full-expression comprises call of S::S(int)void f() { S s2 = 2; // full-expression comprises call of S::S(int)if (S(3).v()) // full-expression includes lvalue-to-rvalue and int to bool conversions,// performed before temporary is deleted at end of full-expression{ }bool b = noexcept(S(4)); // exception specification of destructor of S considered for noexcept// full-expression is destruction of s2 at end of block}struct B { B(S = S(0));};
B b[2] = { B(), B() }; // full-expression is the entire initialization// including the destruction of temporaries — *end example*]
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6360)
[*Note [2](#note-2)*:
The evaluation of a full-expression can include the
evaluation of subexpressions that are not lexically part of the
full-expression[.](#6.sentence-1)
For example, subexpressions involved in evaluating
default arguments ([[dcl.fct.default]](dcl.fct.default "9.3.4.7Default arguments")) are considered to
be created in the expression that calls the function, not the expression
that defines the default argument[.](#6.sentence-2)
— *end note*]
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6370)
Reading an object designated by a volatile glvalue ([[basic.lval]](basic.lval "7.2.1Value category")),
modifying an object,
producing an injected declaration ([[expr.const]](expr.const "7.7Constant expressions")),
calling a library I/O function, or
calling a function that does any of those operations
are all [*side effects*](#def:side_effects "6.10.1Sequential execution[intro.execution]"),
which are changes in the state of the execution or translation environment[.](#7.sentence-1)
[*Evaluation*](#def:evaluation "6.10.1Sequential execution[intro.execution]") of an expression (or a
subexpression) in general includes both value computations (including
determining the identity of an object for glvalue evaluation and fetching
a value previously assigned to an object for prvalue evaluation) and
initiation of side effects[.](#7.sentence-2)
When a call to a library I/O function
returns or an access through a volatile glvalue is evaluated, the side
effect is considered complete, even though some external actions implied
by the call (such as the I/O itself) or by the volatile access
may not have completed yet[.](#7.sentence-3)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6389)
[*Sequenced before*](#def:sequenced_before "6.10.1Sequential execution[intro.execution]") is an asymmetric, transitive, pair-wise relation between
evaluations executed by a single thread ([[intro.multithread]](intro.multithread "6.10.2Multi-threaded executions and data races")), which induces
a partial order among those evaluations[.](#8.sentence-1)
Given any two evaluations *A* and*B*, if *A* is sequenced before *B* (or, equivalently, *B* is [*sequenced after*](#def:sequenced_after "6.10.1Sequential execution[intro.execution]") *A*),
then the execution of*A* shall precede the execution of *B*[.](#8.sentence-2)
If *A* is not sequenced
before *B* and *B* is not sequenced before *A*, then *A* and*B* are [*unsequenced*](#def:unsequenced "6.10.1Sequential execution[intro.execution]")[.](#8.sentence-3)
[*Note [3](#note-3)*:
The execution of unsequenced
evaluations can overlap[.](#8.sentence-4)
— *end note*]
Evaluations *A* and *B* are[*indeterminately sequenced*](#def:indeterminately_sequenced "6.10.1Sequential execution[intro.execution]") when either *A* is sequenced before*B* or *B* is sequenced before *A*, but it is unspecified which[.](#8.sentence-5)
[*Note [4](#note-4)*:
Indeterminately sequenced evaluations cannot overlap, but either
can be executed first[.](#8.sentence-6)
— *end note*]
An expression *X* is said to be sequenced before
an expression *Y* if
every value computation and every side effect
associated with the expression *X* is sequenced before
every value computation and every side effect
associated with the expression *Y*[.](#8.sentence-7)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6419)
Everyvalue computation andside effect associated with a full-expression is
sequenced before every value computation and side effect associated with the
next full-expression to be evaluated[.](#9.sentence-1)[35](#footnote-35 "As specified in [class.temporary], after a full-expression is evaluated, a sequence of zero or more invocations of destructor functions for temporary objects takes place, usually in reverse order of the construction of each temporary object.")
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6434)
Except where noted, evaluations of operands of individual operators and
of subexpressions of individual expressions are unsequenced[.](#10.sentence-1)
[*Note [5](#note-5)*:
In an expression that is evaluated more than once during the execution
of a program, unsequenced and indeterminately sequenced evaluations of
its subexpressions need not be performed consistently in different
evaluations[.](#10.sentence-2)
— *end note*]
The value computations of the operands of an
operator are sequenced before the value computation of the result of the
operator[.](#10.sentence-3)
The behavior is undefined if
- [(10.1)](#10.1)
a side effect on a memory location ([[intro.memory]](intro.memory "6.8.1Memory model")) or
- [(10.2)](#10.2)
starting or ending the lifetime of an object in a memory location
is unsequenced relative to
- [(10.3)](#10.3)
another side effect on the same memory location,
- [(10.4)](#10.4)
starting or ending the lifetime of an object occupying storage that
overlaps with the memory location, or
- [(10.5)](#10.5)
a value computation using the value of any object in the same memory location,
and the two evaluations are not potentially concurrent ([[intro.multithread]](intro.multithread "6.10.2Multi-threaded executions and data races"))[.](#10.sentence-4)
[*Note [6](#note-6)*:
Starting the lifetime of an object in a memory location can end the lifetime of
objects in other memory locations ([[basic.life]](basic.life "6.8.4Lifetime"))[.](#10.sentence-5)
— *end note*]
[*Note [7](#note-7)*:
The next subclause imposes similar, but more complex restrictions on
potentially concurrent computations[.](#10.sentence-6)
— *end note*]
[*Example [3](#example-3)*: void g(int i) { i = 7, i++, i++; // i becomes 9 i = i++ + 1; // the value of i is incremented i = i++ + i; // undefined behavior i = i + 1; // the value of i is incrementedunion U { int x, y; } u; (u.x = 1, 0) + (u.y = 2, 0); // undefined behavior} — *end example*]
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6490)
When invoking a function *f* (whether or not the function is inline),
every argument expression and
the postfix expression designating *f* are sequenced before
every precondition assertion of *f* ([[dcl.contract.func]](dcl.contract.func "9.4.1General")),
which in turn are sequenced before
every expression or statement
in the body of *f*,
which in turn are sequenced before
every postcondition assertion of *f*[.](#11.sentence-1)
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6502)
For each
- [(12.1)](#12.1)
function invocation,
- [(12.2)](#12.2)
evaluation of an [*await-expression*](expr.await#nt:await-expression "7.6.2.4Await[expr.await]") ([[expr.await]](expr.await "7.6.2.4Await")), or
- [(12.3)](#12.3)
evaluation of a [*throw-expression*](expr.throw#nt:throw-expression "7.6.18Throwing an exception[expr.throw]") ([[expr.throw]](expr.throw "7.6.18Throwing an exception"))
*F*,
each evaluation that does not occur within *F* but is evaluated on the same thread and as part of the same signal handler (if any)
is either sequenced before all evaluations that occur within *F* or sequenced after all evaluations that occur within *F*;[36](#footnote-36 "In other words, function executions do not interleave with each other.") if *F* invokes or resumes a coroutine ([[expr.await]](expr.await "7.6.2.4Await")),
only evaluations
subsequent to the previous suspension (if any) and
prior to the next suspension (if any)
are considered to occur within *F*[.](#12.sentence-1)
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6524)
Several contexts in C++ cause evaluation of a function call, even
though no corresponding function call syntax appears in the translation
unit[.](#13.sentence-1)
[*Example [4](#example-4)*:
Evaluation of a [*new-expression*](expr.new#nt:new-expression "7.6.2.8New[expr.new]") invokes one or more allocation
and constructor functions; see [[expr.new]](expr.new "7.6.2.8New")[.](#13.sentence-2)
For another example,
invocation of a conversion function ([[class.conv.fct]](class.conv.fct "11.4.8.3Conversion functions")) can arise in
contexts in which no function call syntax appears[.](#13.sentence-3)
— *end example*]
[14](#14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6535)
The sequencing constraints on the execution of the called function (as
described above) are features of the function calls as evaluated,
regardless of the syntax of the expression that calls the function[.](#14.sentence-1)
[15](#15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6543)
If a signal handler is executed as a result of a call to the std::raise function, then the execution of the handler is sequenced after the invocation
of the std::raise function and before its return[.](#15.sentence-1)
[*Note [8](#note-8)*:
When a signal is received for another reason, the execution of the
signal handler is usually unsequenced with respect to the rest of the program[.](#15.sentence-2)
— *end note*]
[16](#16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6552)
During the evaluation of an expression
as a core constant expression ([[expr.const]](expr.const "7.7Constant expressions")),
evaluations of operands of individual operators and
of subexpressions of individual expressions
that are otherwise either unsequenced or indeterminately sequenced
are evaluated in lexical order[.](#16.sentence-1)
[35)](#footnote-35)[35)](#footnoteref-35)
As specified
in [[class.temporary]](class.temporary "6.8.7Temporary objects"), after a full-expression is evaluated, a sequence of
zero or more invocations of destructor functions for temporary objects takes
place, usually in reverse order of the construction of each temporary object[.](#footnote-35.sentence-1)
[36)](#footnote-36)[36)](#footnoteref-36)
In other words,
function executions do not interleave with each other[.](#footnote-36.sentence-1)