Init
This commit is contained in:
419
cppdraft/intro/execution.md
Normal file
419
cppdraft/intro/execution.md
Normal 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.4 Automatic 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.4 Await")), 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.1 Sequential 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.1 General [dcl.init.general]") or
|
||||
of a (possibly parenthesized) [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1 General [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.1 General [dcl.init.general]") of the form = [*initializer-clause*](dcl.init.general#nt:initializer-clause "9.5.1 General [dcl.init.general]") are the constituent expressions of the [*initializer-clause*](dcl.init.general#nt:initializer-clause "9.5.1 General [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.1 General [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.1 Sequential execution [intro.execution]") of an expression E are
|
||||
|
||||
- [(3.1)](#3.1)
|
||||
|
||||
the constituent expressions of E's operands ([[expr.prop]](expr.prop "7.2 Properties 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.1 General [expr.prim.lambda.general]") ([[expr.prim.lambda]](expr.prim.lambda "7.5.6 Lambda expressions")),
|
||||
the initialization of the entities captured by copy and
|
||||
the constituent expressions of the [*initializer*](dcl.init.general#nt:initializer "9.5.1 General [dcl.init.general]") of the [*init-capture*](expr.prim.lambda.capture#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]")*s*,
|
||||
|
||||
- [(3.4)](#3.4)
|
||||
|
||||
if E is a [function call](expr.call "7.6.1.3 Function call [expr.call]") or implicitly invokes a function,
|
||||
the constituent expressions of each default argument ([[dcl.fct.default]](dcl.fct.default "9.3.4.7 Default arguments"))
|
||||
used in the call, or
|
||||
|
||||
- [(3.5)](#3.5)
|
||||
|
||||
if E creates an aggregate object ([[dcl.init.aggr]](dcl.init.aggr "9.5.2 Aggregates")),
|
||||
the constituent expressions of each default member initializer ([[class.mem]](class.mem "11.4 Class 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.1 Sequential 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.4 Compound statement or block [stmt.block]") of a [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") are not subexpressions of the [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]")[.](#4.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
The [*potentially-evaluated subexpressions*](#def:subexpression,potentially-evaluated "6.10.1 Sequential execution [intro.execution]") of
|
||||
an expression, conversion, or [*initializer*](dcl.init.general#nt:initializer "9.5.1 General [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.3 Context 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.1 Sequential execution [intro.execution]") is
|
||||
|
||||
- [(5.1)](#5.1)
|
||||
|
||||
an [unevaluated operand](expr.context#def:unevaluated_operand "7.2.3 Context dependence [expr.context]"),
|
||||
|
||||
- [(5.2)](#5.2)
|
||||
|
||||
a [*constant-expression*](expr.const#nt:constant-expression "7.7 Constant expressions [expr.const]") ([[expr.const]](expr.const "7.7 Constant expressions")),
|
||||
|
||||
- [(5.3)](#5.3)
|
||||
|
||||
an immediate invocation ([[expr.const]](expr.const "7.7 Constant expressions")),
|
||||
|
||||
- [(5.4)](#5.4)
|
||||
|
||||
an [*init-declarator*](dcl.decl.general#nt:init-declarator "9.3.1 General [dcl.decl.general]") ([[dcl.decl]](dcl.decl "9.3 Declarators"))
|
||||
(including such introduced by a structured binding ([[dcl.struct.bind]](dcl.struct.bind "9.7 Structured binding declarations"))) or
|
||||
a [*mem-initializer*](class.base.init#nt:mem-initializer "11.9.3 Initializing bases and members [class.base.init]") ([[class.base.init]](class.base.init "11.9.3 Initializing 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.7 Temporary objects"))
|
||||
whose lifetime has not been extended,
|
||||
|
||||
- [(5.6)](#5.6)
|
||||
|
||||
the predicate of a contract assertion ([[basic.contract]](basic.contract "6.11 Contract 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.7 Default 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.1 Value category")),
|
||||
modifying an object,
|
||||
producing an injected declaration ([[expr.const]](expr.const "7.7 Constant 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.1 Sequential execution [intro.execution]"),
|
||||
which are changes in the state of the execution or translation environment[.](#7.sentence-1)
|
||||
|
||||
[*Evaluation*](#def:evaluation "6.10.1 Sequential 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.1 Sequential execution [intro.execution]") is an asymmetric, transitive, pair-wise relation between
|
||||
evaluations executed by a single thread ([[intro.multithread]](intro.multithread "6.10.2 Multi-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.1 Sequential 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.1 Sequential 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.1 Sequential 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.1 Memory 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.2 Multi-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.4 Lifetime"))[.](#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.1 General")),
|
||||
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.4 Await [expr.await]") ([[expr.await]](expr.await "7.6.2.4 Await")), or
|
||||
|
||||
- [(12.3)](#12.3)
|
||||
|
||||
evaluation of a [*throw-expression*](expr.throw#nt:throw-expression "7.6.18 Throwing an exception [expr.throw]") ([[expr.throw]](expr.throw "7.6.18 Throwing 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.4 Await")),
|
||||
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.8 New [expr.new]") invokes one or more allocation
|
||||
and constructor functions; see [[expr.new]](expr.new "7.6.2.8 New")[.](#13.sentence-2)
|
||||
|
||||
For another example,
|
||||
invocation of a conversion function ([[class.conv.fct]](class.conv.fct "11.4.8.3 Conversion 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.7 Constant 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.7 Temporary 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)
|
||||
Reference in New Issue
Block a user