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

181
cppdraft/intro/abstract.md Normal file
View File

@@ -0,0 +1,181 @@
[intro.abstract]
# 4 General principles [[intro]](./#intro)
## 4.1 Implementation compliance [[intro.compliance]](intro.compliance#intro.abstract)
### 4.1.2 Abstract machine [intro.abstract]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L904)
The semantic descriptions in this document define a
parameterized nondeterministic abstract machine[.](#1.sentence-1)
This document
places no requirement on the structure of conforming
implementations[.](#1.sentence-2)
In particular, they need not copy or emulate the
structure of the abstract machine[.](#1.sentence-3)
Rather, conforming implementations are required to emulate (only) the observable
behavior of the abstract machine as explained below[.](#1.sentence-4)[5](#footnote-5 "This provision is sometimes called the “as-if” rule, because an implementation is free to disregard any requirement of this document as long as the result is as if the requirement had been obeyed, as far as can be determined from the observable behavior of the program. For instance, an actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no side effects affecting the observable behavior of the program are produced.")
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L929)
Certain aspects and operations of the abstract machine are described in this
document as implementation-defined behavior (for example,sizeof(int))[.](#2.sentence-1)
These constitute the parameters of the abstract machine[.](#2.sentence-2)
Each implementation shall include documentation describing its characteristics
and behavior in these respects[.](#2.sentence-3)[6](#footnote-6 "This documentation also includes conditionally-supported constructs and locale-specific behavior. See [intro.compliance.general].")
Such documentation shall define the instance of the
abstract machine that corresponds to that implementation (referred to as the
“corresponding instance” below)[.](#2.sentence-4)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L945)
Certain other aspects and operations of the abstract machine are
described in this document as unspecified behavior (for example,
order of evaluation of arguments in a function call ([[expr.call]](expr.call "7.6.1.3Function call")))[.](#3.sentence-1)
Where possible, this
document defines a set of allowable behaviors[.](#3.sentence-2)
These
define the nondeterministic aspects of the abstract machine[.](#3.sentence-3)
An instance
of the abstract machine can thus have more than one possible execution
for a given program and a given input[.](#3.sentence-4)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L956)
Certain other operations are described in this document as
undefined behavior (for example, the effect of
attempting to modify a const object)[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L962)
Certain events in the execution of a program
are termed [*observable checkpoints*](#def:checkpoints,observable "4.1.2Abstract machine[intro.abstract]")[.](#5.sentence-1)
[*Note [1](#note-1)*:
A call to std::observable_checkpoint ([[utility.undefined]](utility.undefined "22.2.9Undefined behavior"))
is an observable checkpoint,
as are certain parts of
the evaluation of contract assertions ([[basic.contract]](basic.contract "6.11Contract assertions"))[.](#5.sentence-2)
— *end note*]
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L972)
The [*defined prefix*](#def:prefix,defined "4.1.2Abstract machine[intro.abstract]") of an execution
comprises the operations O for which for every undefined operation U there is an observable checkpoint C such that O happens before C andC happens before U[.](#6.sentence-1)
[*Note [2](#note-2)*:
The undefined behavior that arises from a data race ([[intro.races]](intro.races "6.10.2.2Data races"))
occurs on all participating threads[.](#6.sentence-2)
— *end note*]
A conforming implementation executing a well-formed program shall
produce the observable behavior
of the defined prefix
of one of the possible executions
of the corresponding instance
of the abstract machine with the
same program and the same input[.](#6.sentence-3)
If the selected execution contains an undefined operation,
the implementation executing that program with that input
may produce arbitrary additional observable behavior afterwards[.](#6.sentence-4)
If the execution contains an operation specified as having erroneous behavior,
the implementation is permitted to issue a diagnostic and
is permitted to terminate the execution
at an unspecified time after that operation[.](#6.sentence-5)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L1003)
*Recommended practice*: An implementation should issue a diagnostic when such an operation is executed[.](#7.sentence-1)
[*Note [3](#note-3)*:
An implementation can issue a diagnostic
if it can determine that erroneous behavior is reachable
under an implementation-specific set of assumptions about the program behavior,
which can result in false positives[.](#7.sentence-2)
— *end note*]
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L1013)
The following specify the[*observable behavior*](#def:behavior,observable "4.1.2Abstract machine[intro.abstract]") of the program:
- [(8.1)](#8.1)
Accesses through volatile glvalues are evaluated strictly according to the
rules of the abstract machine[.](#8.1.sentence-1)
- [(8.2)](#8.2)
Data is delivered to the host environment to be written into files (See also: ISO/IEC 9899:2024, 7.21.3)[.](#8.2.sentence-1)
[*Note [4](#note-4)*:
Delivering such data
is followed by an observable checkpoint ([[cstdio.syn]](cstdio.syn "31.13.1Header <cstdio> synopsis"))[.](#8.2.sentence-2)
Not all host environments provide access to file contents before program termination[.](#8.2.sentence-3)
— *end note*]
- [(8.3)](#8.3)
The input and output dynamics of interactive devices shall take
place in such a fashion that prompting output is actually delivered before a program waits for input[.](#8.3.sentence-1)
What constitutes an interactive device isimplementation-defined[.](#8.3.sentence-2)
[*Note [5](#note-5)*:
More stringent correspondences between abstract and actual
semantics can be defined by each implementation[.](#8.sentence-2)
— *end note*]
[5)](#footnote-5)[5)](#footnoteref-5)
This provision is
sometimes called the “as-if” rule, because an implementation is free to
disregard any requirement of this document as long as the result
is as if the requirement had been obeyed, as far as can be determined
from the observable behavior of the program[.](#footnote-5.sentence-1)
For instance, an actual
implementation need not evaluate part of an expression if it can deduce that its
value is not used and that noside effects affecting the
observable behavior of the program are produced[.](#footnote-5.sentence-2)
[6)](#footnote-6)[6)](#footnoteref-6)
This documentation also includes
conditionally-supported constructs and locale-specific behavior[.](#footnote-6.sentence-1)
See [[intro.compliance.general]](intro.compliance.general "4.1.1General")[.](#footnote-6.sentence-2)

View File

@@ -0,0 +1,390 @@
[intro.compliance]
# 4 General principles [[intro]](./#intro)
## 4.1 Implementation compliance [intro.compliance]
### [4.1.1](#general) General [[intro.compliance.general]](intro.compliance.general)
[1](#general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L742)
The set of[*diagnosable rules*](#def:diagnosable_rules "4.1.1General[intro.compliance.general]") consists of all syntactic and semantic rules in this document
except for those rules containing an explicit notation that
“no diagnostic is required” or which are described as resulting in
“undefined behavior”[.](#general-1.sentence-1)
[2](#general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L752)
Although this document states only requirements on C++
implementations, those requirements are often easier to understand if
they are phrased as requirements on programs, parts of programs, or
execution of programs[.](#general-2.sentence-1)
Such requirements have the following meaning:
- [(2.1)](#general-2.1)
If a program contains no violations of the rules in[[lex]](lex "5Lexical conventions") through [[exec]](exec "33Execution control library") as well as those specified in [[depr]](depr "Annex D(normative)Compatibility features"),
a conforming implementation shall accept and correctly execute[3](#footnote-3 "“Correct execution” can include undefined behavior and erroneous behavior, depending on the data being processed; see [intro.defs] and [intro.execution].") that program,
except when the implementation's limitations (see below) are exceeded[.](#general-2.1.sentence-1)
- [(2.2)](#general-2.2)
If a program contains a violation of a rule for which no diagnostic is required,
this document places no requirement on implementations
with respect to that program[.](#general-2.2.sentence-1)
- [(2.3)](#general-2.3)
Otherwise, if a program contains
* [(2.3.1)](#general-2.3.1)
a violation of any diagnosable rule,
* [(2.3.2)](#general-2.3.2)
a preprocessing translation unit with
a #warning preprocessing directive ([[cpp.error]](cpp.error "15.9Diagnostic directives")),
* [(2.3.3)](#general-2.3.3)
an occurrence
of a construct described in this document as “conditionally-supported” when
the implementation does not support that construct, or
* [(2.3.4)](#general-2.3.4)
a contract assertion ([[basic.contract.eval]](basic.contract.eval "6.11.2Evaluation"))
evaluated with a checking semantic
in a manifestly constant-evaluated context ([[expr.const]](expr.const "7.7Constant expressions"))
resulting in a contract violation,
a conforming implementation
shall issue at least one diagnostic message[.](#general-2.3.sentence-1)
[*Note [1](#general-note-1)*:
During template argument deduction and substitution,
certain constructs that in other contexts require a diagnostic
are treated differently;
see [[temp.deduct]](temp.deduct "13.10.3Template argument deduction")[.](#general-2.sentence-2)
— *end note*]
Furthermore, a conforming implementation
shall not accept
- [(2.4)](#general-2.4)
a preprocessing translation unit containing
a #error preprocessing directive ([[cpp.error]](cpp.error "15.9Diagnostic directives")),
- [(2.5)](#general-2.5)
a translation unit with
a [*static_assert-declaration*](dcl.pre#nt:static_assert-declaration "9.1Preamble[dcl.pre]") that fails ([[dcl.pre]](dcl.pre "9.1Preamble")), or
- [(2.6)](#general-2.6)
a contract assertion evaluated with a terminating semantic ([[basic.contract.eval]](basic.contract.eval "6.11.2Evaluation"))
in a manifestly constant-evaluated context ([[expr.const]](expr.const "7.7Constant expressions"))
resulting in a contract violation[.](#general-2.sentence-3)
[3](#general-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L821)
For classes and class templates, the library Clauses specify partial
definitions[.](#general-3.sentence-1)
[Private members](class.access "11.8Member access control[class.access]") are not
specified, but each implementation shall supply them to complete the
definitions according to the description in the library Clauses[.](#general-3.sentence-2)
[4](#general-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L830)
For functions, function templates, objects, and values, the library
Clauses specify declarations[.](#general-4.sentence-1)
Implementations shall supply definitions
consistent with the descriptions in the library Clauses[.](#general-4.sentence-2)
[5](#general-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L835)
A C++ translation unit ([[lex.phases]](lex.phases "5.2Phases of translation"))
obtains access to the names defined in the library by
including the appropriate standard library header or importing
the appropriate standard library named header unit ([[using.headers]](using.headers "16.4.3.2Headers"))[.](#general-5.sentence-1)
[6](#general-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L841)
The templates, classes, functions, and objects in the library have
external [linkage](basic.link "6.7Program and linkage[basic.link]")[.](#general-6.sentence-1)
The implementation provides
definitions for standard library entities, as necessary, while combining
translation units to form a complete C++ program ([[lex.phases]](lex.phases "5.2Phases of translation"))[.](#general-6.sentence-2)
[7](#general-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L848)
An implementation is either a[*hosted implementation*](#def:implementation,hosted "4.1.1General[intro.compliance.general]") or a[*freestanding implementation*](#def:implementation,freestanding "4.1.1General[intro.compliance.general]")[.](#general-7.sentence-1)
A freestanding
implementation is one in which execution may take place without the benefit of
an operating system[.](#general-7.sentence-2)
A hosted implementation
supports all the facilities described in this document, while
a freestanding implementation
supports the entire C++ language
described in [[lex]](lex "5Lexical conventions") through [[cpp]](cpp "15Preprocessing directives") and
the subset of the library facilities described in [[compliance]](compliance "16.4.2.5Freestanding implementations")[.](#general-7.sentence-3)
[8](#general-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L862)
It isimplementation-defined
whether the implementation is a[*hardened implementation*](#def:implementation,hardened "4.1.1General[intro.compliance.general]")[.](#general-8.sentence-1)
If it is a hardened implementation,
violating a hardened precondition
results in a contract violation ([[structure.specifications]](structure.specifications "16.3.2.4Detailed specifications"))[.](#general-8.sentence-2)
[9](#general-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L871)
An implementation is encouraged to document its limitations in
the size or complexity of the programs it can successfully process,
if possible and where known[.](#general-9.sentence-1)
[[implimits]](implimits "Annex B(informative)Implementation quantities") lists some quantities that can be subject to limitations and
a potential minimum supported value for each quantity[.](#general-9.sentence-2)
[10](#general-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L878)
A conforming implementation may use an implementation-defined version
of the Unicode Standard that is a later version than the one
referenced in [[intro.refs]](intro.refs "2Normative references")[.](#general-10.sentence-1)
[11](#general-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L883)
A conforming implementation may have extensions (including
additional library functions), provided they do not alter the
behavior of any well-formed program[.](#general-11.sentence-1)
Implementations are required to diagnose programs that use such
extensions that are ill-formed according to this document[.](#general-11.sentence-2)
Having done so, however, they can compile and execute such programs[.](#general-11.sentence-3)
[12](#general-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L891)
Each implementation shall include documentation that identifies all
conditionally-supported constructs that it does not support and defines all locale-specific characteristics[.](#general-12.sentence-1)[4](#footnote-4 "This documentation also defines implementation-defined behavior; see [intro.abstract].")
[3)](#footnote-3)[3)](#footnoteref-3)
“Correct execution” can include undefined behavior
and erroneous behavior, depending on
the data being processed; see [[intro.defs]](intro.defs "3Terms and definitions") and [[intro.execution]](intro.execution "6.10.1Sequential execution")[.](#footnote-3.sentence-1)
[4)](#footnote-4)[4)](#footnoteref-4)
This documentation also defines implementation-defined behavior;
see [[intro.abstract]](#intro.abstract "4.1.2Abstract machine")[.](#footnote-4.sentence-1)
### [4.1.2](#intro.abstract) Abstract machine [[intro.abstract]](intro.abstract)
[1](#intro.abstract-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L904)
The semantic descriptions in this document define a
parameterized nondeterministic abstract machine[.](#intro.abstract-1.sentence-1)
This document
places no requirement on the structure of conforming
implementations[.](#intro.abstract-1.sentence-2)
In particular, they need not copy or emulate the
structure of the abstract machine[.](#intro.abstract-1.sentence-3)
Rather, conforming implementations are required to emulate (only) the observable
behavior of the abstract machine as explained below[.](#intro.abstract-1.sentence-4)[5](#footnote-5 "This provision is sometimes called the “as-if” rule, because an implementation is free to disregard any requirement of this document as long as the result is as if the requirement had been obeyed, as far as can be determined from the observable behavior of the program. For instance, an actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no side effects affecting the observable behavior of the program are produced.")
[2](#intro.abstract-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L929)
Certain aspects and operations of the abstract machine are described in this
document as implementation-defined behavior (for example,sizeof(int))[.](#intro.abstract-2.sentence-1)
These constitute the parameters of the abstract machine[.](#intro.abstract-2.sentence-2)
Each implementation shall include documentation describing its characteristics
and behavior in these respects[.](#intro.abstract-2.sentence-3)[6](#footnote-6 "This documentation also includes conditionally-supported constructs and locale-specific behavior. See [intro.compliance.general].")
Such documentation shall define the instance of the
abstract machine that corresponds to that implementation (referred to as the
“corresponding instance” below)[.](#intro.abstract-2.sentence-4)
[3](#intro.abstract-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L945)
Certain other aspects and operations of the abstract machine are
described in this document as unspecified behavior (for example,
order of evaluation of arguments in a function call ([[expr.call]](expr.call "7.6.1.3Function call")))[.](#intro.abstract-3.sentence-1)
Where possible, this
document defines a set of allowable behaviors[.](#intro.abstract-3.sentence-2)
These
define the nondeterministic aspects of the abstract machine[.](#intro.abstract-3.sentence-3)
An instance
of the abstract machine can thus have more than one possible execution
for a given program and a given input[.](#intro.abstract-3.sentence-4)
[4](#intro.abstract-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L956)
Certain other operations are described in this document as
undefined behavior (for example, the effect of
attempting to modify a const object)[.](#intro.abstract-4.sentence-1)
[5](#intro.abstract-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L962)
Certain events in the execution of a program
are termed [*observable checkpoints*](#def:checkpoints,observable "4.1.2Abstract machine[intro.abstract]")[.](#intro.abstract-5.sentence-1)
[*Note [1](#intro.abstract-note-1)*:
A call to std::observable_checkpoint ([[utility.undefined]](utility.undefined "22.2.9Undefined behavior"))
is an observable checkpoint,
as are certain parts of
the evaluation of contract assertions ([[basic.contract]](basic.contract "6.11Contract assertions"))[.](#intro.abstract-5.sentence-2)
— *end note*]
[6](#intro.abstract-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L972)
The [*defined prefix*](#def:prefix,defined "4.1.2Abstract machine[intro.abstract]") of an execution
comprises the operations O for which for every undefined operation U there is an observable checkpoint C such that O happens before C andC happens before U[.](#intro.abstract-6.sentence-1)
[*Note [2](#intro.abstract-note-2)*:
The undefined behavior that arises from a data race ([[intro.races]](intro.races "6.10.2.2Data races"))
occurs on all participating threads[.](#intro.abstract-6.sentence-2)
— *end note*]
A conforming implementation executing a well-formed program shall
produce the observable behavior
of the defined prefix
of one of the possible executions
of the corresponding instance
of the abstract machine with the
same program and the same input[.](#intro.abstract-6.sentence-3)
If the selected execution contains an undefined operation,
the implementation executing that program with that input
may produce arbitrary additional observable behavior afterwards[.](#intro.abstract-6.sentence-4)
If the execution contains an operation specified as having erroneous behavior,
the implementation is permitted to issue a diagnostic and
is permitted to terminate the execution
at an unspecified time after that operation[.](#intro.abstract-6.sentence-5)
[7](#intro.abstract-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L1003)
*Recommended practice*: An implementation should issue a diagnostic when such an operation is executed[.](#intro.abstract-7.sentence-1)
[*Note [3](#intro.abstract-note-3)*:
An implementation can issue a diagnostic
if it can determine that erroneous behavior is reachable
under an implementation-specific set of assumptions about the program behavior,
which can result in false positives[.](#intro.abstract-7.sentence-2)
— *end note*]
[8](#intro.abstract-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L1013)
The following specify the[*observable behavior*](#def:behavior,observable "4.1.2Abstract machine[intro.abstract]") of the program:
- [(8.1)](#intro.abstract-8.1)
Accesses through volatile glvalues are evaluated strictly according to the
rules of the abstract machine[.](#intro.abstract-8.1.sentence-1)
- [(8.2)](#intro.abstract-8.2)
Data is delivered to the host environment to be written into files (See also: ISO/IEC 9899:2024, 7.21.3)[.](#intro.abstract-8.2.sentence-1)
[*Note [4](#intro.abstract-note-4)*:
Delivering such data
is followed by an observable checkpoint ([[cstdio.syn]](cstdio.syn "31.13.1Header <cstdio> synopsis"))[.](#intro.abstract-8.2.sentence-2)
Not all host environments provide access to file contents before program termination[.](#intro.abstract-8.2.sentence-3)
— *end note*]
- [(8.3)](#intro.abstract-8.3)
The input and output dynamics of interactive devices shall take
place in such a fashion that prompting output is actually delivered before a program waits for input[.](#intro.abstract-8.3.sentence-1)
What constitutes an interactive device isimplementation-defined[.](#intro.abstract-8.3.sentence-2)
[*Note [5](#intro.abstract-note-5)*:
More stringent correspondences between abstract and actual
semantics can be defined by each implementation[.](#intro.abstract-8.sentence-2)
— *end note*]
[5)](#footnote-5)[5)](#footnoteref-5)
This provision is
sometimes called the “as-if” rule, because an implementation is free to
disregard any requirement of this document as long as the result
is as if the requirement had been obeyed, as far as can be determined
from the observable behavior of the program[.](#footnote-5.sentence-1)
For instance, an actual
implementation need not evaluate part of an expression if it can deduce that its
value is not used and that noside effects affecting the
observable behavior of the program are produced[.](#footnote-5.sentence-2)
[6)](#footnote-6)[6)](#footnoteref-6)
This documentation also includes
conditionally-supported constructs and locale-specific behavior[.](#footnote-6.sentence-1)
See [[intro.compliance.general]](#general "4.1.1General")[.](#footnote-6.sentence-2)

View File

@@ -0,0 +1,214 @@
[intro.compliance.general]
# 4 General principles [[intro]](./#intro)
## 4.1 Implementation compliance [[intro.compliance]](intro.compliance#general)
### 4.1.1 General [intro.compliance.general]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L742)
The set of[*diagnosable rules*](#def:diagnosable_rules "4.1.1General[intro.compliance.general]") consists of all syntactic and semantic rules in this document
except for those rules containing an explicit notation that
“no diagnostic is required” or which are described as resulting in
“undefined behavior”[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L752)
Although this document states only requirements on C++
implementations, those requirements are often easier to understand if
they are phrased as requirements on programs, parts of programs, or
execution of programs[.](#2.sentence-1)
Such requirements have the following meaning:
- [(2.1)](#2.1)
If a program contains no violations of the rules in[[lex]](lex "5Lexical conventions") through [[exec]](exec "33Execution control library") as well as those specified in [[depr]](depr "Annex D(normative)Compatibility features"),
a conforming implementation shall accept and correctly execute[3](#footnote-3 "“Correct execution” can include undefined behavior and erroneous behavior, depending on the data being processed; see [intro.defs] and [intro.execution].") that program,
except when the implementation's limitations (see below) are exceeded[.](#2.1.sentence-1)
- [(2.2)](#2.2)
If a program contains a violation of a rule for which no diagnostic is required,
this document places no requirement on implementations
with respect to that program[.](#2.2.sentence-1)
- [(2.3)](#2.3)
Otherwise, if a program contains
* [(2.3.1)](#2.3.1)
a violation of any diagnosable rule,
* [(2.3.2)](#2.3.2)
a preprocessing translation unit with
a #warning preprocessing directive ([[cpp.error]](cpp.error "15.9Diagnostic directives")),
* [(2.3.3)](#2.3.3)
an occurrence
of a construct described in this document as “conditionally-supported” when
the implementation does not support that construct, or
* [(2.3.4)](#2.3.4)
a contract assertion ([[basic.contract.eval]](basic.contract.eval "6.11.2Evaluation"))
evaluated with a checking semantic
in a manifestly constant-evaluated context ([[expr.const]](expr.const "7.7Constant expressions"))
resulting in a contract violation,
a conforming implementation
shall issue at least one diagnostic message[.](#2.3.sentence-1)
[*Note [1](#note-1)*:
During template argument deduction and substitution,
certain constructs that in other contexts require a diagnostic
are treated differently;
see [[temp.deduct]](temp.deduct "13.10.3Template argument deduction")[.](#2.sentence-2)
— *end note*]
Furthermore, a conforming implementation
shall not accept
- [(2.4)](#2.4)
a preprocessing translation unit containing
a #error preprocessing directive ([[cpp.error]](cpp.error "15.9Diagnostic directives")),
- [(2.5)](#2.5)
a translation unit with
a [*static_assert-declaration*](dcl.pre#nt:static_assert-declaration "9.1Preamble[dcl.pre]") that fails ([[dcl.pre]](dcl.pre "9.1Preamble")), or
- [(2.6)](#2.6)
a contract assertion evaluated with a terminating semantic ([[basic.contract.eval]](basic.contract.eval "6.11.2Evaluation"))
in a manifestly constant-evaluated context ([[expr.const]](expr.const "7.7Constant expressions"))
resulting in a contract violation[.](#2.sentence-3)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L821)
For classes and class templates, the library Clauses specify partial
definitions[.](#3.sentence-1)
[Private members](class.access "11.8Member access control[class.access]") are not
specified, but each implementation shall supply them to complete the
definitions according to the description in the library Clauses[.](#3.sentence-2)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L830)
For functions, function templates, objects, and values, the library
Clauses specify declarations[.](#4.sentence-1)
Implementations shall supply definitions
consistent with the descriptions in the library Clauses[.](#4.sentence-2)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L835)
A C++ translation unit ([[lex.phases]](lex.phases "5.2Phases of translation"))
obtains access to the names defined in the library by
including the appropriate standard library header or importing
the appropriate standard library named header unit ([[using.headers]](using.headers "16.4.3.2Headers"))[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L841)
The templates, classes, functions, and objects in the library have
external [linkage](basic.link "6.7Program and linkage[basic.link]")[.](#6.sentence-1)
The implementation provides
definitions for standard library entities, as necessary, while combining
translation units to form a complete C++ program ([[lex.phases]](lex.phases "5.2Phases of translation"))[.](#6.sentence-2)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L848)
An implementation is either a[*hosted implementation*](#def:implementation,hosted "4.1.1General[intro.compliance.general]") or a[*freestanding implementation*](#def:implementation,freestanding "4.1.1General[intro.compliance.general]")[.](#7.sentence-1)
A freestanding
implementation is one in which execution may take place without the benefit of
an operating system[.](#7.sentence-2)
A hosted implementation
supports all the facilities described in this document, while
a freestanding implementation
supports the entire C++ language
described in [[lex]](lex "5Lexical conventions") through [[cpp]](cpp "15Preprocessing directives") and
the subset of the library facilities described in [[compliance]](compliance "16.4.2.5Freestanding implementations")[.](#7.sentence-3)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L862)
It isimplementation-defined
whether the implementation is a[*hardened implementation*](#def:implementation,hardened "4.1.1General[intro.compliance.general]")[.](#8.sentence-1)
If it is a hardened implementation,
violating a hardened precondition
results in a contract violation ([[structure.specifications]](structure.specifications "16.3.2.4Detailed specifications"))[.](#8.sentence-2)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L871)
An implementation is encouraged to document its limitations in
the size or complexity of the programs it can successfully process,
if possible and where known[.](#9.sentence-1)
[[implimits]](implimits "Annex B(informative)Implementation quantities") lists some quantities that can be subject to limitations and
a potential minimum supported value for each quantity[.](#9.sentence-2)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L878)
A conforming implementation may use an implementation-defined version
of the Unicode Standard that is a later version than the one
referenced in [[intro.refs]](intro.refs "2Normative references")[.](#10.sentence-1)
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L883)
A conforming implementation may have extensions (including
additional library functions), provided they do not alter the
behavior of any well-formed program[.](#11.sentence-1)
Implementations are required to diagnose programs that use such
extensions that are ill-formed according to this document[.](#11.sentence-2)
Having done so, however, they can compile and execute such programs[.](#11.sentence-3)
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L891)
Each implementation shall include documentation that identifies all
conditionally-supported constructs that it does not support and defines all locale-specific characteristics[.](#12.sentence-1)[4](#footnote-4 "This documentation also defines implementation-defined behavior; see [intro.abstract].")
[3)](#footnote-3)[3)](#footnoteref-3)
“Correct execution” can include undefined behavior
and erroneous behavior, depending on
the data being processed; see [[intro.defs]](intro.defs "3Terms and definitions") and [[intro.execution]](intro.execution "6.10.1Sequential execution")[.](#footnote-3.sentence-1)
[4)](#footnote-4)[4)](#footnoteref-4)
This documentation also defines implementation-defined behavior;
see [[intro.abstract]](intro.abstract "4.1.2Abstract machine")[.](#footnote-4.sentence-1)

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)

100
cppdraft/intro/memory.md Normal file
View File

@@ -0,0 +1,100 @@
[intro.memory]
# 6 Basics [[basic]](./#basic)
## 6.8 Memory and objects [[basic.memobj]](basic.memobj#intro.memory)
### 6.8.1 Memory model [intro.memory]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3348)
The fundamental storage unit in the C++ memory model is the[*byte*](#def:byte "6.8.1Memory model[intro.memory]")[.](#1.sentence-1)
A byte is at least large enough to contain
the ordinary literal encoding of any element of the basicliteral character set ([[lex.charset]](lex.charset "5.3.1Character sets"))
and the eight-bit code units of the UnicodeUTF-8 encoding form
and is composed of a contiguous sequence of
bits,[19](#footnote-19 "The number of bits in a byte is reported by the macro CHAR_­BIT in the header <climits>.") the number of which is implementation-defined[.](#1.sentence-2)
The memory available to a C++ program consists of one or more sequences of
contiguous bytes[.](#1.sentence-3)
Every byte has a unique address[.](#1.sentence-4)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3370)
[*Note [1](#note-1)*:
The representation of types is described
in [[basic.types.general]](basic.types.general "6.9.1General")[.](#2.sentence-1)
— *end note*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3376)
A [*memory location*](#def:memory_location "6.8.1Memory model[intro.memory]") is
the storage occupied by the object representation of
either an object of scalar type that is not a bit-field
or a maximal sequence of adjacent bit-fields all having nonzero width[.](#3.sentence-1)
[*Note [2](#note-2)*:
Various
features of the language, such as references and virtual functions, might
involve additional memory locations that are not accessible to programs but are
managed by the implementation[.](#3.sentence-2)
— *end note*]
Two or more [threads of
execution](intro.multithread#def:thread_of_execution "6.10.2Multi-threaded executions and data races[intro.multithread]") can access separate memory
locations without interfering with each other[.](#3.sentence-3)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3391)
[*Note [3](#note-3)*:
Thus a bit-field and an adjacent non-bit-field are in separate memory
locations, and therefore can be concurrently updated by two threads of execution
without interference[.](#4.sentence-1)
The same applies to two bit-fields, if one is declared
inside a nested struct declaration and the other is not, or if the two are
separated by a zero-length bit-field declaration, or if they are separated by a
non-bit-field declaration[.](#4.sentence-2)
It is not safe to concurrently update two bit-fields
in the same struct if all fields between them are also bit-fields of nonzero
width[.](#4.sentence-3)
— *end note*]
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3403)
[*Example [1](#example-1)*:
A class declared asstruct {char a; int b:5,
c:11, :0,
d:8; struct {int ee:8;} e;}; contains four separate memory locations: The member a and bit-fieldsd and e.ee are each separate memory locations, and can be
modified concurrently without interfering with each other[.](#5.sentence-1)
The bit-fieldsb and c together constitute the fourth memory location[.](#5.sentence-2)
The
bit-fields b and c cannot be concurrently modified, butb and a, for example, can be[.](#5.sentence-3)
— *end example*]
[19)](#footnote-19)[19)](#footnoteref-19)
The number of bits in a byte is reported by the macroCHAR_BIT in the header [<climits>](climits.syn#header:%3cclimits%3e "17.3.6Header <climits> synopsis[climits.syn]")[.](#footnote-19.sentence-1)

View File

@@ -0,0 +1,856 @@
[intro.multithread]
# 6 Basics [[basic]](./#basic)
## 6.10 Program execution [[basic.exec]](basic.exec#intro.multithread)
### 6.10.2 Multi-threaded executions and data races [intro.multithread]
#### [6.10.2.1](#general) General [[intro.multithread.general]](intro.multithread.general)
[1](#general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6564)
A [*thread of execution*](#def:thread_of_execution "6.10.2.1General[intro.multithread.general]") (also known as a [*thread*](#def:thread "6.10.2.1General[intro.multithread.general]")) is a single flow of
control within a program, including the initial invocation of a specific
top-level function, and recursively including every function invocation
subsequently executed by the thread[.](#general-1.sentence-1)
[*Note [1](#general-note-1)*:
When one thread creates another,
the initial call to the top-level function of the new thread is executed by the
new thread, not by the creating thread[.](#general-1.sentence-2)
— *end note*]
Every thread in a program can
potentially use every object and function in a program[.](#general-1.sentence-3)[37](#footnote-37 "An object with automatic or thread storage duration ([basic.stc]) is associated with one specific thread, and can be accessed by a different thread only indirectly through a pointer or reference ([basic.compound]).")
Under a hosted
implementation, a C++ program can have more than one thread running
concurrently[.](#general-1.sentence-4)
The execution of each thread proceeds as defined by the remainder
of this document[.](#general-1.sentence-5)
The execution of the entire program consists of an execution
of all of its threads[.](#general-1.sentence-6)
[*Note [2](#general-note-2)*:
Usually the execution can be viewed as an
interleaving of all its threads[.](#general-1.sentence-7)
However, some kinds of atomic operations, for
example, allow executions inconsistent with a simple interleaving, as described
below[.](#general-1.sentence-8)
— *end note*]
Under a freestanding implementation, it is implementation-defined whether a program can
have more than one thread of execution[.](#general-1.sentence-9)
[2](#general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6600)
For a signal handler that is not executed as a result of a call to thestd::raise function, it is unspecified which thread of execution
contains the signal handler invocation[.](#general-2.sentence-1)
[37)](#footnote-37)[37)](#footnoteref-37)
An object
with automatic or thread storage duration ([[basic.stc]](basic.stc "6.8.6Storage duration")) is associated with
one specific thread, and can be accessed by a different thread only indirectly
through a pointer or reference ([[basic.compound]](basic.compound "6.9.4Compound types"))[.](#footnote-37.sentence-1)
#### [6.10.2.2](#intro.races) Data races [[intro.races]](intro.races)
[1](#intro.races-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6607)
The value of an object visible to a thread T at a particular point is the
initial value of the object, a value assigned to the object by T, or a
value assigned to the object by another thread, according to the rules below[.](#intro.races-1.sentence-1)
[*Note [1](#intro.races-note-1)*:
In some cases, there might instead be undefined behavior[.](#intro.races-1.sentence-2)
Much of this
subclause is motivated by the desire to support atomic operations with explicit
and detailed visibility constraints[.](#intro.races-1.sentence-3)
However, it also implicitly supports a
simpler view for more restricted programs[.](#intro.races-1.sentence-4)
— *end note*]
[2](#intro.races-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6618)
Two expression evaluations [*conflict*](#def:conflict "6.10.2.2Data races[intro.races]") if one of them
- [(2.1)](#intro.races-2.1)
modifies ([[defns.access]](defns.access "3.1access")) a memory location ([[intro.memory]](intro.memory "6.8.1Memory model")) or
- [(2.2)](#intro.races-2.2)
starts or ends the lifetime of an object in a memory location
and the other one
- [(2.3)](#intro.races-2.3)
reads or modifies the same memory location or
- [(2.4)](#intro.races-2.4)
starts or ends the lifetime of an object occupying storage that
overlaps with the memory location[.](#intro.races-2.sentence-1)
[*Note [2](#intro.races-note-2)*:
A modification can still conflict
even if it does not alter the value of any bits[.](#intro.races-2.sentence-2)
— *end note*]
[3](#intro.races-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6639)
The library defines a number of atomic operations ([[atomics]](atomics "32.5Atomic operations")) and
operations on mutexes ([[thread]](thread "32Concurrency support library")) that are specially identified as
synchronization operations[.](#intro.races-3.sentence-1)
These operations play a special role in making
assignments in one thread visible to another[.](#intro.races-3.sentence-2)
A synchronization operation on one
or more memory locations is either an acquire operation, a
release operation, or both an acquire and release operation[.](#intro.races-3.sentence-3)
A synchronization
operation without an associated memory location is a fence and can be either an
acquire fence, a release fence, or both an acquire and release fence[.](#intro.races-3.sentence-4)
In
addition, there are relaxed atomic operations, which are not synchronization
operations, and atomic read-modify-write operations, which have special
characteristics[.](#intro.races-3.sentence-5)
[*Note [3](#intro.races-note-3)*:
For example, a call that acquires a mutex will
perform an acquire operation on the locations comprising the mutex[.](#intro.races-3.sentence-6)
Correspondingly, a call that releases the same mutex will perform a release
operation on those same locations[.](#intro.races-3.sentence-7)
Informally, performing a release operation onA forces priorside effects on other memory locations to become visible
to other threads that later perform a consume or an acquire operation onA[.](#intro.races-3.sentence-8)
“Relaxed” atomic operations are not synchronization operations even
though, like synchronization operations, they cannot contribute to data races[.](#intro.races-3.sentence-9)
— *end note*]
[4](#intro.races-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6664)
All modifications to a particular atomic object M occur in some
particular total order, called the [*modification order*](#def:modification_order "6.10.2.2Data races[intro.races]") of M[.](#intro.races-4.sentence-1)
[*Note [4](#intro.races-note-4)*:
There is a separate order for each
atomic object[.](#intro.races-4.sentence-2)
There is no requirement that these can be combined into a single
total order for all objects[.](#intro.races-4.sentence-3)
In general this will be impossible since different
threads can observe modifications to different objects in inconsistent orders[.](#intro.races-4.sentence-4)
— *end note*]
[5](#intro.races-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6674)
A [*release sequence*](#def:release_sequence "6.10.2.2Data races[intro.races]") headed
by a release operation A on an atomic object M is a maximal contiguous sub-sequence ofside effects in the modification order of M,
where the first operation is A, and
every subsequent operation is an atomic read-modify-write operation[.](#intro.races-5.sentence-1)
[6](#intro.races-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6683)
Certain library calls [*synchronize with*](#def:synchronize_with "6.10.2.2Data races[intro.races]") other library calls performed by
another thread[.](#intro.races-6.sentence-1)
For example, an atomic store-release synchronizes with a
load-acquire that takes its value from the store ([[atomics.order]](atomics.order "32.5.4Order and consistency"))[.](#intro.races-6.sentence-2)
[*Note [5](#intro.races-note-5)*:
Except in the specified cases, reading a later value does not
necessarily ensure visibility as described below[.](#intro.races-6.sentence-3)
Such a requirement would
sometimes interfere with efficient implementation[.](#intro.races-6.sentence-4)
— *end note*]
[*Note [6](#intro.races-note-6)*:
The
specifications of the synchronization operations define when one reads the value
written by another[.](#intro.races-6.sentence-5)
For atomic objects, the definition is clear[.](#intro.races-6.sentence-6)
All operations
on a given mutex occur in a single total order[.](#intro.races-6.sentence-7)
Each mutex acquisition “reads
the value written” by the last mutex release[.](#intro.races-6.sentence-8)
— *end note*]
[7](#intro.races-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6700)
An evaluation A [*happens before*](#def:happens_before "6.10.2.2Data races[intro.races]") an evaluation B (or, equivalently, B happens after A)
if either
- [(7.1)](#intro.races-7.1)
A is sequenced before B, or
- [(7.2)](#intro.races-7.2)
A synchronizes with B, or
- [(7.3)](#intro.races-7.3)
A happens before X and X happens before B[.](#intro.races-7.sentence-1)
[*Note [7](#intro.races-note-7)*:
An evaluation does not happen before itself[.](#intro.races-7.sentence-2)
— *end note*]
[8](#intro.races-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6713)
An evaluation A [*strongly happens before*](#def:strongly_happens_before "6.10.2.2Data races[intro.races]") an evaluation D if, either
- [(8.1)](#intro.races-8.1)
A is sequenced before D, or
- [(8.2)](#intro.races-8.2)
A synchronizes with D, and
both A and D are
sequentially consistent atomic operations ([[atomics.order]](atomics.order "32.5.4Order and consistency")), or
- [(8.3)](#intro.races-8.3)
there are evaluations B and C such that A is sequenced before B,B happens before C, andC is sequenced before D, or
- [(8.4)](#intro.races-8.4)
there is an evaluation B such thatA strongly happens before B, andB strongly happens before D[.](#intro.races-8.sentence-1)
[*Note [8](#intro.races-note-8)*:
Informally, if A strongly happens before B,
then A appears to be evaluated before B in all contexts[.](#intro.races-8.sentence-2)
— *end note*]
[9](#intro.races-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6735)
A [*visible side effect*](#def:side_effects,visible "6.10.2.2Data races[intro.races]") A on a scalar object or bit-field M with respect to a value computation B of M satisfies the
conditions:
- [(9.1)](#intro.races-9.1)
A happens before B and
- [(9.2)](#intro.races-9.2)
there is no otherside effect X to M such that A happens before X and X happens before B[.](#intro.races-9.sentence-1)
The value of a non-atomic scalar object or bit-field M, as determined by
evaluation B, is the value stored by thevisible side effect A[.](#intro.races-9.sentence-2)
[*Note [9](#intro.races-note-9)*:
If there is ambiguity about which side effect to a
non-atomic object or bit-field is visible, then the behavior is either
unspecified or undefined[.](#intro.races-9.sentence-3)
— *end note*]
[*Note [10](#intro.races-note-10)*:
This states that operations on
ordinary objects are not visibly reordered[.](#intro.races-9.sentence-4)
This is not actually detectable
without data races, but is needed to ensure that data races, as defined
below, and with suitable restrictions on the use of atomics, correspond to data
races in a simple interleaved (sequentially consistent) execution[.](#intro.races-9.sentence-5)
— *end note*]
[10](#intro.races-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6764)
The value of an
atomic object M, as determined by evaluation B, is the value
stored by some unspecified
side effect A that modifies M, where B does not happen
before A[.](#intro.races-10.sentence-1)
[*Note [11](#intro.races-note-11)*:
The set of such side effects is also restricted by the rest of the rules
described here, and in particular, by the coherence requirements below[.](#intro.races-10.sentence-2)
— *end note*]
[11](#intro.races-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6775)
If an operation A that modifies an atomic object M happens before
an operation B that modifies M, then A is earlier
than B in the modification order of M[.](#intro.races-11.sentence-1)
[*Note [12](#intro.races-note-12)*:
This requirement is known as write-write coherence[.](#intro.races-11.sentence-2)
— *end note*]
[12](#intro.races-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6784)
If avalue computation A of an atomic object M happens before a
value computation B of M, and A takes its value from a side
effect X on M, then the value computed by B is either
the value stored by X or the value stored by aside effect Y on M,
where Y follows X in the modification order of M[.](#intro.races-12.sentence-1)
[*Note [13](#intro.races-note-13)*:
This requirement is known as read-read coherence[.](#intro.races-12.sentence-2)
— *end note*]
[13](#intro.races-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6799)
If avalue computation A of an atomic object M happens before an
operation B that modifies M, then A takes its value from a side
effect X on M, where X precedes B in the
modification order of M[.](#intro.races-13.sentence-1)
[*Note [14](#intro.races-note-14)*:
This requirement is known as
read-write coherence[.](#intro.races-13.sentence-2)
— *end note*]
[14](#intro.races-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6812)
If aside effect X on an atomic object M happens before a value
computation B of M, then the evaluation B takes its
value from X or from aside effect Y that follows X in the modification order of M[.](#intro.races-14.sentence-1)
[*Note [15](#intro.races-note-15)*:
This requirement is known as write-read coherence[.](#intro.races-14.sentence-2)
— *end note*]
[15](#intro.races-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6825)
[*Note [16](#intro.races-note-16)*:
The four preceding coherence requirements effectively disallow
compiler reordering of atomic operations to a single object, even if both
operations are relaxed loads[.](#intro.races-15.sentence-1)
This effectively makes the cache coherence
guarantee provided by most hardware available to C++ atomic operations[.](#intro.races-15.sentence-2)
— *end note*]
[16](#intro.races-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6833)
[*Note [17](#intro.races-note-17)*:
The value observed by a load of an atomic depends on the “happens
before” relation, which depends on the values observed by loads of atomics[.](#intro.races-16.sentence-1)
The intended reading is that there must exist an
association of atomic loads with modifications they observe that, together with
suitably chosen modification orders and the “happens before” relation derived
as described above, satisfy the resulting constraints as imposed here[.](#intro.races-16.sentence-2)
— *end note*]
[17](#intro.races-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6843)
Two actions are [*potentially concurrent*](#def:potentially_concurrent "6.10.2.2Data races[intro.races]") if
- [(17.1)](#intro.races-17.1)
they are performed by different threads, or
- [(17.2)](#intro.races-17.2)
they are unsequenced, at least one is performed by a signal handler, and
they are not both performed by the same signal handler invocation[.](#intro.races-17.sentence-1)
The execution of a program contains a [*data race*](#def:data_race "6.10.2.2Data races[intro.races]") if it contains two
potentially concurrent conflicting actions, at least one of which is not atomic,
and neither happens before the other,
except for the special case for signal handlers described below[.](#intro.races-17.sentence-2)
Any such data race results in undefined
behavior[.](#intro.races-17.sentence-3)
[*Note [18](#intro.races-note-18)*:
It can be shown that programs that correctly use mutexes
and memory_order::seq_cst operations to prevent all data races and use no
other synchronization operations behave as if the operations executed by their
constituent threads were simply interleaved, with eachvalue computation of an
object being taken from the lastside effect on that object in that
interleaving[.](#intro.races-17.sentence-4)
This is normally referred to as “sequential consistency”[.](#intro.races-17.sentence-5)
However, this applies only to data-race-free programs, and data-race-free
programs cannot observe most program transformations that do not change
single-threaded program semantics[.](#intro.races-17.sentence-6)
In fact, most single-threaded program
transformations remain possible, since any program that behaves
differently as a result has undefined behavior[.](#intro.races-17.sentence-7)
— *end note*]
[18](#intro.races-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6874)
Two accesses to the same non-bit-field object
of type volatile std::sig_atomic_t do not
result in a data race if both occur in the same thread, even if one or more
occurs in a signal handler[.](#intro.races-18.sentence-1)
For each signal handler invocation, evaluations
performed by the thread invoking a signal handler can be divided into two
groups A and B, such that no evaluations inB happen before evaluations in A, and the
evaluations of such volatile std::sig_atomic_t objects take values as though
all evaluations in A happened before the execution of the signal
handler and the execution of the signal handler happened before all evaluations
in B[.](#intro.races-18.sentence-2)
[19](#intro.races-19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6887)
[*Note [19](#intro.races-note-19)*:
Compiler transformations that introduce assignments to a potentially
shared memory location that would not be modified by the abstract machine are
generally precluded by this document, since such an assignment might overwrite
another assignment by a different thread in cases in which an abstract machine
execution would not have encountered a data race[.](#intro.races-19.sentence-1)
This includes implementations
of data member assignment that overwrite adjacent members in separate memory
locations[.](#intro.races-19.sentence-2)
Reordering of atomic loads in cases in which the atomics in question
might alias is also generally precluded, since this could violate the coherence
rules[.](#intro.races-19.sentence-3)
— *end note*]
[20](#intro.races-20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6900)
[*Note [20](#intro.races-note-20)*:
It is possible that transformations that introduce a speculative read of a potentially
shared memory location do not preserve the semantics of the C++ program as
defined in this document, since they potentially introduce a data race[.](#intro.races-20.sentence-1)
However,
they are typically valid in the context of an optimizing compiler that targets a
specific machine with well-defined semantics for data races[.](#intro.races-20.sentence-2)
They would be
invalid for a hypothetical machine that is not tolerant of races or provides
hardware race detection[.](#intro.races-20.sentence-3)
— *end note*]
#### [6.10.2.3](#intro.progress) Forward progress [[intro.progress]](intro.progress)
[1](#intro.progress-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6913)
The implementation may assume that any thread will eventually do one of the
following:
- [(1.1)](#intro.progress-1.1)
terminate,
- [(1.2)](#intro.progress-1.2)
invoke the function std::this_thread::yield ([[thread.thread.this]](thread.thread.this "32.4.5Namespace this_­thread")),
- [(1.3)](#intro.progress-1.3)
make a call to a library I/O function,
- [(1.4)](#intro.progress-1.4)
perform an access through a volatile glvalue,
- [(1.5)](#intro.progress-1.5)
perform an atomic or synchronization operation
other than an atomic modify-write operation ([[atomics.order]](atomics.order "32.5.4Order and consistency")), or
- [(1.6)](#intro.progress-1.6)
continue execution of a trivial infinite loop ([[stmt.iter.general]](stmt.iter.general "8.6.1General"))[.](#intro.progress-1.sentence-1)
[*Note [1](#intro.progress-note-1)*:
This is intended to allow compiler transformations
such as removal, merging, and reordering of empty loops,
even when termination cannot be proven[.](#intro.progress-1.sentence-2)
An affordance is made for trivial infinite loops,
which cannot be removed nor reordered[.](#intro.progress-1.sentence-3)
— *end note*]
[2](#intro.progress-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6933)
Executions of atomic functions
that are either defined to be lock-free ([[atomics.flag]](atomics.flag "32.5.10Flag type and operations"))
or indicated as lock-free ([[atomics.lockfree]](atomics.lockfree "32.5.5Lock-free property"))
are [*lock-free executions*](#def:lock-free_execution "6.10.2.3Forward progress[intro.progress]")[.](#intro.progress-2.sentence-1)
- [(2.1)](#intro.progress-2.1)
If there is only one thread that is not blocked ([[defns.block]](defns.block "3.6block"))
in a standard library function,
a lock-free execution in that thread shall complete[.](#intro.progress-2.1.sentence-1)
[*Note [2](#intro.progress-note-2)*:
Concurrently executing threads
might prevent progress of a lock-free execution[.](#intro.progress-2.1.sentence-2)
For example,
this situation can occur
with load-locked store-conditional implementations[.](#intro.progress-2.1.sentence-3)
This property is sometimes termed obstruction-free[.](#intro.progress-2.1.sentence-4)
— *end note*]
- [(2.2)](#intro.progress-2.2)
When one or more lock-free executions run concurrently,
at least one should complete[.](#intro.progress-2.2.sentence-1)
[*Note [3](#intro.progress-note-3)*:
It is difficult for some implementations
to provide absolute guarantees to this effect,
since repeated and particularly inopportune interference
from other threads
could prevent forward progress,
e.g.,
by repeatedly stealing a cache line
for unrelated purposes
between load-locked and store-conditional instructions[.](#intro.progress-2.2.sentence-2)
For implementations that follow this recommendation and
ensure that such effects cannot indefinitely delay progress
under expected operating conditions,
such anomalies
can therefore safely be ignored by programmers[.](#intro.progress-2.2.sentence-3)
Outside this document,
this property is sometimes termed lock-free[.](#intro.progress-2.2.sentence-4)
— *end note*]
[3](#intro.progress-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6974)
During the execution of a thread of execution, each of the following is termed
an [*execution step*](#def:execution_step "6.10.2.3Forward progress[intro.progress]"):
- [(3.1)](#intro.progress-3.1)
termination of the thread of execution,
- [(3.2)](#intro.progress-3.2)
performing an access through a volatile glvalue,
- [(3.3)](#intro.progress-3.3)
completion of a call to a library I/O function, or
- [(3.4)](#intro.progress-3.4)
completion of an atomic or synchronization operation
other than an atomic modify-write operation ([[atomics.order]](atomics.order "32.5.4Order and consistency"))[.](#intro.progress-3.sentence-1)
[4](#intro.progress-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6985)
An invocation of a standard library function that blocks ([[defns.block]](defns.block "3.6block"))
is considered to continuously execute execution steps while waiting for the
condition that it blocks on to be satisfied[.](#intro.progress-4.sentence-1)
[*Example [1](#intro.progress-example-1)*:
A library I/O function that blocks until the I/O operation is complete can
be considered to continuously check whether the operation is complete[.](#intro.progress-4.sentence-2)
Each
such check consists of one or more execution steps, for example using
observable behavior of the abstract machine[.](#intro.progress-4.sentence-3)
— *end example*]
[5](#intro.progress-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6996)
[*Note [4](#intro.progress-note-4)*:
Because of this and the preceding requirement regarding what threads of execution
have to perform eventually, it follows that no thread of execution can execute
forever without an execution step occurring[.](#intro.progress-5.sentence-1)
— *end note*]
[6](#intro.progress-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7003)
A thread of execution [*makes progress*](#def:make_progress,thread "6.10.2.3Forward progress[intro.progress]") when an execution step occurs or a
lock-free execution does not complete because there are other concurrent threads
that are not blocked in a standard library function (see above)[.](#intro.progress-6.sentence-1)
[7](#intro.progress-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7009)
For a thread of execution providing [*concurrent forward progress guarantees*](#def:concurrent_forward_progress_guarantees "6.10.2.3Forward progress[intro.progress]"),
the implementation ensures that the thread will eventually make progress for as
long as it has not terminated[.](#intro.progress-7.sentence-1)
[*Note [5](#intro.progress-note-5)*:
This applies regardless of whether or not other threads of execution (if any)
have been or are making progress[.](#intro.progress-7.sentence-2)
To eventually fulfill this requirement means that
this will happen in an unspecified but finite amount of time[.](#intro.progress-7.sentence-3)
— *end note*]
[8](#intro.progress-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7020)
It is implementation-defined whether the
implementation-created thread of execution that executesmain ([[basic.start.main]](basic.start.main "6.10.3.1main function")) and the threads of execution created bystd::thread ([[thread.thread.class]](thread.thread.class "32.4.3Class thread"))
or std::jthread ([[thread.jthread.class]](thread.jthread.class "32.4.4Class jthread"))
provide concurrent forward progress guarantees[.](#intro.progress-8.sentence-1)
General-purpose implementations should provide these guarantees[.](#intro.progress-8.sentence-2)
[9](#intro.progress-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7030)
For a thread of execution providing [*parallel forward progress guarantees*](#def:parallel_forward_progress_guarantees "6.10.2.3Forward progress[intro.progress]"),
the implementation is not required to ensure that the thread will eventually make
progress if it has not yet executed any execution step; once this thread has
executed a step, it provides concurrent forward progress guarantees[.](#intro.progress-9.sentence-1)
[10](#intro.progress-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7037)
[*Note [6](#intro.progress-note-6)*:
This does not specify a requirement for when to start this thread of execution,
which will typically be specified by the entity that creates this thread of
execution[.](#intro.progress-10.sentence-1)
For example, a thread of execution that provides concurrent forward
progress guarantees and executes tasks from a set of tasks in an arbitrary order,
one after the other, satisfies the requirements of parallel forward progress for
these tasks[.](#intro.progress-10.sentence-2)
— *end note*]
[11](#intro.progress-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7047)
For a thread of execution providing [*weakly parallel forward progress
guarantees*](#def:weakly_parallel_forward_progress_guarantees "6.10.2.3Forward progress[intro.progress]"), the implementation does not ensure that the thread will eventually
make progress[.](#intro.progress-11.sentence-1)
[12](#intro.progress-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7053)
[*Note [7](#intro.progress-note-7)*:
Threads of execution providing weakly parallel forward progress guarantees cannot
be expected to make progress regardless of whether other threads make progress or
not; however, blocking with forward progress guarantee delegation, as defined below,
can be used to ensure that such threads of execution make progress eventually[.](#intro.progress-12.sentence-1)
— *end note*]
[13](#intro.progress-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7061)
Concurrent forward progress guarantees are stronger than parallel forward progress
guarantees, which in turn are stronger than weakly parallel forward progress
guarantees[.](#intro.progress-13.sentence-1)
[*Note [8](#intro.progress-note-8)*:
For example, some kinds of synchronization between threads of execution might only
make progress if the respective threads of execution provide parallel forward progress
guarantees, but will fail to make progress under weakly parallel guarantees[.](#intro.progress-13.sentence-2)
— *end note*]
[14](#intro.progress-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7071)
When a thread of execution P is specified to[*block with forward progress guarantee delegation*](#def:block_(execution),with_forward_progress_guarantee_delegation "6.10.2.3Forward progress[intro.progress]") on the completion of a set S of threads of execution,
then throughout the whole time of P being blocked on S,
the implementation shall ensure that the forward progress guarantees
provided by at least one thread of execution in S is at least as strong as P's forward progress guarantees[.](#intro.progress-14.sentence-1)
[*Note [9](#intro.progress-note-9)*:
It is unspecified which thread or threads of execution in S are chosen
and for which number of execution steps[.](#intro.progress-14.sentence-2)
The strengthening is not permanent and
not necessarily in place for the rest of the lifetime of the affected thread of
execution[.](#intro.progress-14.sentence-3)
As long as P is blocked, the implementation has to eventually
select and potentially strengthen a thread of execution in S[.](#intro.progress-14.sentence-4)
— *end note*]
Once a thread of execution in S terminates, it is removed from S[.](#intro.progress-14.sentence-5)
Once S is empty, P is unblocked[.](#intro.progress-14.sentence-6)
[15](#intro.progress-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7091)
[*Note [10](#intro.progress-note-10)*:
A thread of execution B thus can temporarily provide an effectively
stronger forward progress guarantee for a certain amount of time, due to a
second thread of execution A being blocked on it with forward
progress guarantee delegation[.](#intro.progress-15.sentence-1)
In turn, if B then blocks with
forward progress guarantee delegation on C, this can also temporarily
provide a stronger forward progress guarantee to C[.](#intro.progress-15.sentence-2)
— *end note*]
[16](#intro.progress-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7101)
[*Note [11](#intro.progress-note-11)*:
If all threads of execution in S finish executing (e.g., they terminate
and do not use blocking synchronization incorrectly), then P's execution
of the operation that blocks with forward progress guarantee delegation will not
result in P's progress guarantee being effectively weakened[.](#intro.progress-16.sentence-1)
— *end note*]
[17](#intro.progress-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7109)
[*Note [12](#intro.progress-note-12)*:
This does not remove any constraints regarding blocking synchronization for
threads of execution providing parallel or weakly parallel forward progress
guarantees because the implementation is not required to strengthen a particular
thread of execution whose too-weak progress guarantee is preventing overall progress[.](#intro.progress-17.sentence-1)
— *end note*]
[18](#intro.progress-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7117)
An implementation should ensure that the last value (in modification order)
assigned by an atomic or synchronization operation will become visible to all
other threads in a finite period of time[.](#intro.progress-18.sentence-1)

View File

@@ -0,0 +1,67 @@
[intro.multithread.general]
# 6 Basics [[basic]](./#basic)
## 6.10 Program execution [[basic.exec]](basic.exec#intro.multithread.general)
### 6.10.2 Multi-threaded executions and data races [[intro.multithread]](intro.multithread#general)
#### 6.10.2.1 General [intro.multithread.general]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6564)
A [*thread of execution*](#def:thread_of_execution "6.10.2.1General[intro.multithread.general]") (also known as a [*thread*](#def:thread "6.10.2.1General[intro.multithread.general]")) is a single flow of
control within a program, including the initial invocation of a specific
top-level function, and recursively including every function invocation
subsequently executed by the thread[.](#1.sentence-1)
[*Note [1](#note-1)*:
When one thread creates another,
the initial call to the top-level function of the new thread is executed by the
new thread, not by the creating thread[.](#1.sentence-2)
— *end note*]
Every thread in a program can
potentially use every object and function in a program[.](#1.sentence-3)[37](#footnote-37 "An object with automatic or thread storage duration ([basic.stc]) is associated with one specific thread, and can be accessed by a different thread only indirectly through a pointer or reference ([basic.compound]).")
Under a hosted
implementation, a C++ program can have more than one thread running
concurrently[.](#1.sentence-4)
The execution of each thread proceeds as defined by the remainder
of this document[.](#1.sentence-5)
The execution of the entire program consists of an execution
of all of its threads[.](#1.sentence-6)
[*Note [2](#note-2)*:
Usually the execution can be viewed as an
interleaving of all its threads[.](#1.sentence-7)
However, some kinds of atomic operations, for
example, allow executions inconsistent with a simple interleaving, as described
below[.](#1.sentence-8)
— *end note*]
Under a freestanding implementation, it is implementation-defined whether a program can
have more than one thread of execution[.](#1.sentence-9)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6600)
For a signal handler that is not executed as a result of a call to thestd::raise function, it is unspecified which thread of execution
contains the signal handler invocation[.](#2.sentence-1)
[37)](#footnote-37)[37)](#footnoteref-37)
An object
with automatic or thread storage duration ([[basic.stc]](basic.stc "6.8.6Storage duration")) is associated with
one specific thread, and can be accessed by a different thread only indirectly
through a pointer or reference ([[basic.compound]](basic.compound "6.9.4Compound types"))[.](#footnote-37.sentence-1)

360
cppdraft/intro/object.md Normal file
View File

@@ -0,0 +1,360 @@
[intro.object]
# 6 Basics [[basic]](./#basic)
## 6.8 Memory and objects [[basic.memobj]](basic.memobj#intro.object)
### 6.8.2 Object model [intro.object]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3427)
The constructs in a C++ program create, destroy, refer to, access, and
manipulate objects[.](#1.sentence-1)
An [*object*](#def:object "6.8.2Object model[intro.object]") is created
by a [definition](basic.def "6.2Declarations and definitions[basic.def]"),
by a [*new-expression*](expr.new#nt:new-expression "7.6.2.8New[expr.new]") ([[expr.new]](expr.new "7.6.2.8New")),
by an operation that implicitly creates objects (see below),
when implicitly changing the active member of a [union](class.union "11.5Unions[class.union]"),
or
when a temporary object is created ([[conv.rval]](conv.rval "7.3.5Temporary materialization conversion"), [[class.temporary]](class.temporary "6.8.7Temporary objects"))[.](#1.sentence-2)
An object occupies a region of storage
in its period of construction ([[class.cdtor]](class.cdtor "11.9.5Construction and destruction")),
throughout its [lifetime](basic.life "6.8.4Lifetime[basic.life]"),
and
in its period of destruction ([[class.cdtor]](class.cdtor "11.9.5Construction and destruction"))[.](#1.sentence-3)
[*Note [1](#note-1)*:
A function is not an object, regardless of whether or not it
occupies storage in the way that objects do[.](#1.sentence-4)
— *end note*]
The properties of an
object are determined when the object is created[.](#1.sentence-5)
An object can have a
name ([[basic.pre]](basic.pre "6.1Preamble"))[.](#1.sentence-6)
An object has a storage
duration ([[basic.stc]](basic.stc "6.8.6Storage duration")) which influences its
lifetime ([[basic.life]](basic.life "6.8.4Lifetime"))[.](#1.sentence-7)
An object has a
type ([[basic.types]](basic.types "6.9Types"))[.](#1.sentence-8)
[*Note [2](#note-2)*:
Some objects are
polymorphic ([[class.virtual]](class.virtual "11.7.3Virtual functions")); the implementation
generates information associated with each such object that makes it
possible to determine that object's type during program execution[.](#1.sentence-9)
— *end note*]
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3460)
Objects can contain other objects, called [*subobjects*](#def:subobject "6.8.2Object model[intro.object]")[.](#2.sentence-1)
A subobject can be
a [*member subobject*](#def:member_subobject "6.8.2Object model[intro.object]") ([[class.mem]](class.mem "11.4Class members")), a [*base class subobject*](#def:base_class_subobject "6.8.2Object model[intro.object]") ([[class.derived]](class.derived "11.7Derived classes")),
or an array element[.](#2.sentence-2)
An object that is not a subobject of any other object is called a [*complete
object*](#def:complete_object "6.8.2Object model[intro.object]")[.](#2.sentence-3)
If an object is created
in storage associated with a member subobject or array element *e* (which may or may not be within its lifetime),
the created object
is a subobject of *e*'s containing object if
- [(2.1)](#2.1)
the lifetime of *e*'s containing object has begun and not ended, and
- [(2.2)](#2.2)
the storage for the new object exactly overlays the storage location associated with *e*, and
- [(2.3)](#2.3)
the new object is of the same type as *e* (ignoring cv-qualification)[.](#2.sentence-4)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3483)
If a complete object is created ([[expr.new]](expr.new "7.6.2.8New"))
in storage associated with another object *e* of type “array of N unsigned char” or
of type “array of N std::byte” ([[cstddef.syn]](cstddef.syn "17.2.1Header <cstddef> synopsis")),
that array [*provides storage*](#def:provides_storage "6.8.2Object model[intro.object]") for the created object if
- [(3.1)](#3.1)
the lifetime of *e* has begun and not ended, and
- [(3.2)](#3.2)
the storage for the new object fits entirely within *e*, and
- [(3.3)](#3.3)
there is no array object that satisfies these constraints nested within *e*[.](#3.sentence-1)
[*Note [3](#note-3)*:
If that portion of the array
previously provided storage for another object,
the lifetime of that object ends
because its storage was reused ([[basic.life]](basic.life "6.8.4Lifetime"))[.](#3.sentence-2)
— *end note*]
[*Example [1](#example-1)*: // assumes that sizeof(int) is equal to 4template<typename ...T>struct AlignedUnion {alignas(T...) unsigned char data[max(sizeof(T)...)];};int f() { AlignedUnion<int, char> au; int *p = new (au.data) int; // OK, au.data provides storagechar *c = new (au.data) char(); // OK, ends lifetime of *pchar *d = new (au.data + 1) char(); return *c + *d; // OK}struct A { unsigned char a[32]; };struct B { unsigned char b[16]; };alignas(int) A a;
B *b = new (a.a + 8) B; // a.a provides storage for *bint *p = new (b->b + 4) int; // b->b provides storage for *p// a.a does not provide storage for *p (directly),// but *p is nested within a (see below) — *end example*]
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3531)
An object *a* is [*nested within*](#def:nested_within "6.8.2Object model[intro.object]") another object *b* if
- [(4.1)](#4.1)
*a* is a subobject of *b*, or
- [(4.2)](#4.2)
*b* provides storage for *a*, or
- [(4.3)](#4.3)
there exists an object *c* where *a* is nested within *c*,
and *c* is nested within *b*[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3545)
For every object x, there is some object called the[*complete object of*](#def:complete_object_of "6.8.2Object model[intro.object]") x, determined as follows:
- [(5.1)](#5.1)
If x is a complete object, then the complete object
of x is itself[.](#5.1.sentence-1)
- [(5.2)](#5.2)
Otherwise, the complete object of x is the complete object
of the (unique) object that contains x[.](#5.2.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3558)
If a complete object, a member subobject, or an array element is of
class type, its type is considered the [*most derived
class*](#def:most_derived_class "6.8.2Object model[intro.object]"), to distinguish it from the class type of any base class subobject;
an object of a most derived class type or of a non-class type is called a[*most derived object*](#def:most_derived_object "6.8.2Object model[intro.object]")[.](#6.sentence-1)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3565)
A [*potentially-overlapping subobject*](#def:potentially-overlapping_subobject "6.8.2Object model[intro.object]") is either:
- [(7.1)](#7.1)
a base class subobject, or
- [(7.2)](#7.2)
a non-static data member
declared with the [no_unique_address](dcl.attr.nouniqueaddr "9.13.11No unique address attribute[dcl.attr.nouniqueaddr]") attribute[.](#7.sentence-1)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3573)
An object has nonzero size if it
- [(8.1)](#8.1)
is not a potentially-overlapping subobject, or
- [(8.2)](#8.2)
is not of class type, or
- [(8.3)](#8.3)
is of a class type with virtual member functions or virtual base classes, or
- [(8.4)](#8.4)
has subobjects of nonzero size or unnamed bit-fields of nonzero length[.](#8.sentence-1)
Otherwise, if the object is a base class subobject
of a standard-layout class type
with no non-static data members,
it has zero size[.](#8.sentence-2)
Otherwise, the circumstances under which the object has zero size
are implementation-defined[.](#8.sentence-3)
Unless it is a [bit-field](class.bit "11.4.10Bit-fields[class.bit]"),
an object with nonzero size
shall occupy one or more bytes of storage,
including every byte that is occupied in full or in part
by any of its subobjects[.](#8.sentence-4)
An object of trivially copyable or
standard-layout type ([[basic.types.general]](basic.types.general "6.9.1General")) shall occupy contiguous bytes of
storage[.](#8.sentence-5)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3600)
An object is a [*potentially non-unique object*](#def:object,potentially_non-unique "6.8.2Object model[intro.object]") if it is
- [(9.1)](#9.1)
a string literal object ([[lex.string]](lex.string "5.13.5String literals")),
- [(9.2)](#9.2)
the backing array of an initializer list ([[dcl.init.ref]](dcl.init.ref "9.5.4References")), or
- [(9.3)](#9.3)
the object introduced by a call to std::meta::reflect_constant_array or std::meta::reflect_constant_string ([[meta.reflection.array]](meta.reflection.array "21.4.15Promoting to static storage arrays")), or
- [(9.4)](#9.4)
a subobject thereof[.](#9.sentence-1)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3614)
Unless an object is a bit-field or a subobject of zero size, the
address of that object is the address of the first byte it occupies[.](#10.sentence-1)
Two objects
with overlapping lifetimes
that are not bit-fields
may have the same address if
- [(10.1)](#10.1)
one is nested within the other,
- [(10.2)](#10.2)
at least one is a subobject of zero size and they are not of similar types ([[conv.qual]](conv.qual "7.3.6Qualification conversions")),
or
- [(10.3)](#10.3)
they are both potentially non-unique objects;
otherwise, they have distinct addresses
and occupy disjoint bytes of storage[.](#10.sentence-2)[20](#footnote-20 "Under the “as-if” rule an implementation is allowed to store two objects at the same machine address or not store an object at all if the program cannot observe the difference ([intro.execution]).")
[*Example [2](#example-2)*: static const char test1 = 'x';static const char test2 = 'x';const bool b = &test1 != &test2; // always truestatic const char (&r) [] = "x";static const char *s = "x";static std::initializer_list<char> il = { 'x' };const bool b2 = r != il.begin(); // unspecified resultconst bool b3 = r != s; // unspecified resultconst bool b4 = il.begin() != &test1; // always trueconst bool b5 = r != &test1; // always true — *end example*]
The address of a non-bit-field subobject of zero size is
the address of an unspecified byte of storage
occupied by the complete object of that subobject[.](#10.sentence-3)
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3656)
Some operations are described as[*implicitly creating objects*](#def:object,implicit_creation "6.8.2Object model[intro.object]") within a specified region of storage[.](#11.sentence-1)
For each operation that is specified as implicitly creating objects,
that operation implicitly creates and starts the lifetime of
zero or more objects of implicit-lifetime types ([[basic.types.general]](basic.types.general#term.implicit.lifetime.type "6.9.1General"))
in its specified region of storage
if doing so would result in the program having defined behavior[.](#11.sentence-2)
If no such set of objects would give the program defined behavior,
the behavior of the program is undefined[.](#11.sentence-3)
If multiple such sets of objects would give the program defined behavior,
it is unspecified which such set of objects is created[.](#11.sentence-4)
[*Note [4](#note-4)*:
Such operations do not start the lifetimes of subobjects of such objects
that are not themselves of implicit-lifetime types[.](#11.sentence-5)
— *end note*]
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3674)
Further, after implicitly creating objects within a specified region of storage,
some operations are described as producing a pointer to a[*suitable created object*](#def:object,suitable_created "6.8.2Object model[intro.object]")[.](#12.sentence-1)
These operations select one of the implicitly-created objects
whose address is the address of the start of the region of storage,
and produce a pointer value that points to that object,
if that value would result in the program having defined behavior[.](#12.sentence-2)
If no such pointer value would give the program defined behavior,
the behavior of the program is undefined[.](#12.sentence-3)
If multiple such pointer values would give the program defined behavior,
it is unspecified which such pointer value is produced[.](#12.sentence-4)
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3687)
[*Example [3](#example-3)*: #include <cstdlib>struct X { int a, b; };
X *make_x() {// The call to std::malloc implicitly creates an object of type X// and its subobjects a and b, and returns a pointer to that X object// (or an object that is pointer-interconvertible ([[basic.compound]](basic.compound "6.9.4Compound types")) with it),// in order to give the subsequent class member access operations// defined behavior. X *p = (X*)std::malloc(sizeof(struct X));
p->a = 1;
p->b = 2; return p;} — *end example*]
[14](#14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3706)
Except during constant evaluation,
an operation that begins the lifetime of
an array of unsigned char or std::byte implicitly creates objects within the region of storage occupied by the array[.](#14.sentence-1)
[*Note [5](#note-5)*:
The array object provides storage for these objects[.](#14.sentence-2)
— *end note*]
Except during constant evaluation,
any implicit or explicit invocation of a function
named operator new or operator new[] implicitly creates objects in the returned region of storage and
returns a pointer to a suitable created object[.](#14.sentence-3)
[*Note [6](#note-6)*:
Some functions in the C++ standard library implicitly create
objects ([[obj.lifetime]](obj.lifetime "20.2.6Explicit lifetime management"), [[c.malloc]](c.malloc "20.2.12C library memory allocation"), [[mem.res.public]](mem.res.public "20.5.2.2Public member functions"), [[bit.cast]](bit.cast "22.11.3Function template bit_­cast"), [[cstring.syn]](cstring.syn "27.5.1Header <cstring> synopsis"))[.](#14.sentence-4)
— *end note*]
[20)](#footnote-20)[20)](#footnoteref-20)
Under the “as-if” rule an
implementation is allowed to store two objects at the same machine address or
not store an object at all if the program cannot observe the
difference ([[intro.execution]](intro.execution "6.10.1Sequential execution"))[.](#footnote-20.sentence-1)

331
cppdraft/intro/progress.md Normal file
View File

@@ -0,0 +1,331 @@
[intro.progress]
# 6 Basics [[basic]](./#basic)
## 6.10 Program execution [[basic.exec]](basic.exec#intro.progress)
### 6.10.2 Multi-threaded executions and data races [[intro.multithread]](intro.multithread#intro.progress)
#### 6.10.2.3 Forward progress [intro.progress]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6913)
The implementation may assume that any thread will eventually do one of the
following:
- [(1.1)](#1.1)
terminate,
- [(1.2)](#1.2)
invoke the function std::this_thread::yield ([[thread.thread.this]](thread.thread.this "32.4.5Namespace this_­thread")),
- [(1.3)](#1.3)
make a call to a library I/O function,
- [(1.4)](#1.4)
perform an access through a volatile glvalue,
- [(1.5)](#1.5)
perform an atomic or synchronization operation
other than an atomic modify-write operation ([[atomics.order]](atomics.order "32.5.4Order and consistency")), or
- [(1.6)](#1.6)
continue execution of a trivial infinite loop ([[stmt.iter.general]](stmt.iter.general "8.6.1General"))[.](#1.sentence-1)
[*Note [1](#note-1)*:
This is intended to allow compiler transformations
such as removal, merging, and reordering of empty loops,
even when termination cannot be proven[.](#1.sentence-2)
An affordance is made for trivial infinite loops,
which cannot be removed nor reordered[.](#1.sentence-3)
— *end note*]
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6933)
Executions of atomic functions
that are either defined to be lock-free ([[atomics.flag]](atomics.flag "32.5.10Flag type and operations"))
or indicated as lock-free ([[atomics.lockfree]](atomics.lockfree "32.5.5Lock-free property"))
are [*lock-free executions*](#def:lock-free_execution "6.10.2.3Forward progress[intro.progress]")[.](#2.sentence-1)
- [(2.1)](#2.1)
If there is only one thread that is not blocked ([[defns.block]](defns.block "3.6block"))
in a standard library function,
a lock-free execution in that thread shall complete[.](#2.1.sentence-1)
[*Note [2](#note-2)*:
Concurrently executing threads
might prevent progress of a lock-free execution[.](#2.1.sentence-2)
For example,
this situation can occur
with load-locked store-conditional implementations[.](#2.1.sentence-3)
This property is sometimes termed obstruction-free[.](#2.1.sentence-4)
— *end note*]
- [(2.2)](#2.2)
When one or more lock-free executions run concurrently,
at least one should complete[.](#2.2.sentence-1)
[*Note [3](#note-3)*:
It is difficult for some implementations
to provide absolute guarantees to this effect,
since repeated and particularly inopportune interference
from other threads
could prevent forward progress,
e.g.,
by repeatedly stealing a cache line
for unrelated purposes
between load-locked and store-conditional instructions[.](#2.2.sentence-2)
For implementations that follow this recommendation and
ensure that such effects cannot indefinitely delay progress
under expected operating conditions,
such anomalies
can therefore safely be ignored by programmers[.](#2.2.sentence-3)
Outside this document,
this property is sometimes termed lock-free[.](#2.2.sentence-4)
— *end note*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6974)
During the execution of a thread of execution, each of the following is termed
an [*execution step*](#def:execution_step "6.10.2.3Forward progress[intro.progress]"):
- [(3.1)](#3.1)
termination of the thread of execution,
- [(3.2)](#3.2)
performing an access through a volatile glvalue,
- [(3.3)](#3.3)
completion of a call to a library I/O function, or
- [(3.4)](#3.4)
completion of an atomic or synchronization operation
other than an atomic modify-write operation ([[atomics.order]](atomics.order "32.5.4Order and consistency"))[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6985)
An invocation of a standard library function that blocks ([[defns.block]](defns.block "3.6block"))
is considered to continuously execute execution steps while waiting for the
condition that it blocks on to be satisfied[.](#4.sentence-1)
[*Example [1](#example-1)*:
A library I/O function that blocks until the I/O operation is complete can
be considered to continuously check whether the operation is complete[.](#4.sentence-2)
Each
such check consists of one or more execution steps, for example using
observable behavior of the abstract machine[.](#4.sentence-3)
— *end example*]
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6996)
[*Note [4](#note-4)*:
Because of this and the preceding requirement regarding what threads of execution
have to perform eventually, it follows that no thread of execution can execute
forever without an execution step occurring[.](#5.sentence-1)
— *end note*]
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7003)
A thread of execution [*makes progress*](#def:make_progress,thread "6.10.2.3Forward progress[intro.progress]") when an execution step occurs or a
lock-free execution does not complete because there are other concurrent threads
that are not blocked in a standard library function (see above)[.](#6.sentence-1)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7009)
For a thread of execution providing [*concurrent forward progress guarantees*](#def:concurrent_forward_progress_guarantees "6.10.2.3Forward progress[intro.progress]"),
the implementation ensures that the thread will eventually make progress for as
long as it has not terminated[.](#7.sentence-1)
[*Note [5](#note-5)*:
This applies regardless of whether or not other threads of execution (if any)
have been or are making progress[.](#7.sentence-2)
To eventually fulfill this requirement means that
this will happen in an unspecified but finite amount of time[.](#7.sentence-3)
— *end note*]
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7020)
It is implementation-defined whether the
implementation-created thread of execution that executesmain ([[basic.start.main]](basic.start.main "6.10.3.1main function")) and the threads of execution created bystd::thread ([[thread.thread.class]](thread.thread.class "32.4.3Class thread"))
or std::jthread ([[thread.jthread.class]](thread.jthread.class "32.4.4Class jthread"))
provide concurrent forward progress guarantees[.](#8.sentence-1)
General-purpose implementations should provide these guarantees[.](#8.sentence-2)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7030)
For a thread of execution providing [*parallel forward progress guarantees*](#def:parallel_forward_progress_guarantees "6.10.2.3Forward progress[intro.progress]"),
the implementation is not required to ensure that the thread will eventually make
progress if it has not yet executed any execution step; once this thread has
executed a step, it provides concurrent forward progress guarantees[.](#9.sentence-1)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7037)
[*Note [6](#note-6)*:
This does not specify a requirement for when to start this thread of execution,
which will typically be specified by the entity that creates this thread of
execution[.](#10.sentence-1)
For example, a thread of execution that provides concurrent forward
progress guarantees and executes tasks from a set of tasks in an arbitrary order,
one after the other, satisfies the requirements of parallel forward progress for
these tasks[.](#10.sentence-2)
— *end note*]
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7047)
For a thread of execution providing [*weakly parallel forward progress
guarantees*](#def:weakly_parallel_forward_progress_guarantees "6.10.2.3Forward progress[intro.progress]"), the implementation does not ensure that the thread will eventually
make progress[.](#11.sentence-1)
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7053)
[*Note [7](#note-7)*:
Threads of execution providing weakly parallel forward progress guarantees cannot
be expected to make progress regardless of whether other threads make progress or
not; however, blocking with forward progress guarantee delegation, as defined below,
can be used to ensure that such threads of execution make progress eventually[.](#12.sentence-1)
— *end note*]
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7061)
Concurrent forward progress guarantees are stronger than parallel forward progress
guarantees, which in turn are stronger than weakly parallel forward progress
guarantees[.](#13.sentence-1)
[*Note [8](#note-8)*:
For example, some kinds of synchronization between threads of execution might only
make progress if the respective threads of execution provide parallel forward progress
guarantees, but will fail to make progress under weakly parallel guarantees[.](#13.sentence-2)
— *end note*]
[14](#14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7071)
When a thread of execution P is specified to[*block with forward progress guarantee delegation*](#def:block_(execution),with_forward_progress_guarantee_delegation "6.10.2.3Forward progress[intro.progress]") on the completion of a set S of threads of execution,
then throughout the whole time of P being blocked on S,
the implementation shall ensure that the forward progress guarantees
provided by at least one thread of execution in S is at least as strong as P's forward progress guarantees[.](#14.sentence-1)
[*Note [9](#note-9)*:
It is unspecified which thread or threads of execution in S are chosen
and for which number of execution steps[.](#14.sentence-2)
The strengthening is not permanent and
not necessarily in place for the rest of the lifetime of the affected thread of
execution[.](#14.sentence-3)
As long as P is blocked, the implementation has to eventually
select and potentially strengthen a thread of execution in S[.](#14.sentence-4)
— *end note*]
Once a thread of execution in S terminates, it is removed from S[.](#14.sentence-5)
Once S is empty, P is unblocked[.](#14.sentence-6)
[15](#15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7091)
[*Note [10](#note-10)*:
A thread of execution B thus can temporarily provide an effectively
stronger forward progress guarantee for a certain amount of time, due to a
second thread of execution A being blocked on it with forward
progress guarantee delegation[.](#15.sentence-1)
In turn, if B then blocks with
forward progress guarantee delegation on C, this can also temporarily
provide a stronger forward progress guarantee to C[.](#15.sentence-2)
— *end note*]
[16](#16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7101)
[*Note [11](#note-11)*:
If all threads of execution in S finish executing (e.g., they terminate
and do not use blocking synchronization incorrectly), then P's execution
of the operation that blocks with forward progress guarantee delegation will not
result in P's progress guarantee being effectively weakened[.](#16.sentence-1)
— *end note*]
[17](#17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7109)
[*Note [12](#note-12)*:
This does not remove any constraints regarding blocking synchronization for
threads of execution providing parallel or weakly parallel forward progress
guarantees because the implementation is not required to strengthen a particular
thread of execution whose too-weak progress guarantee is preventing overall progress[.](#17.sentence-1)
— *end note*]
[18](#18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7117)
An implementation should ensure that the last value (in modification order)
assigned by an atomic or synchronization operation will become visible to all
other threads in a finite period of time[.](#18.sentence-1)

472
cppdraft/intro/races.md Normal file
View File

@@ -0,0 +1,472 @@
[intro.races]
# 6 Basics [[basic]](./#basic)
## 6.10 Program execution [[basic.exec]](basic.exec#intro.races)
### 6.10.2 Multi-threaded executions and data races [[intro.multithread]](intro.multithread#intro.races)
#### 6.10.2.2 Data races [intro.races]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6607)
The value of an object visible to a thread T at a particular point is the
initial value of the object, a value assigned to the object by T, or a
value assigned to the object by another thread, according to the rules below[.](#1.sentence-1)
[*Note [1](#note-1)*:
In some cases, there might instead be undefined behavior[.](#1.sentence-2)
Much of this
subclause is motivated by the desire to support atomic operations with explicit
and detailed visibility constraints[.](#1.sentence-3)
However, it also implicitly supports a
simpler view for more restricted programs[.](#1.sentence-4)
— *end note*]
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6618)
Two expression evaluations [*conflict*](#def:conflict "6.10.2.2Data races[intro.races]") if one of them
- [(2.1)](#2.1)
modifies ([[defns.access]](defns.access "3.1access")) a memory location ([[intro.memory]](intro.memory "6.8.1Memory model")) or
- [(2.2)](#2.2)
starts or ends the lifetime of an object in a memory location
and the other one
- [(2.3)](#2.3)
reads or modifies the same memory location or
- [(2.4)](#2.4)
starts or ends the lifetime of an object occupying storage that
overlaps with the memory location[.](#2.sentence-1)
[*Note [2](#note-2)*:
A modification can still conflict
even if it does not alter the value of any bits[.](#2.sentence-2)
— *end note*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6639)
The library defines a number of atomic operations ([[atomics]](atomics "32.5Atomic operations")) and
operations on mutexes ([[thread]](thread "32Concurrency support library")) that are specially identified as
synchronization operations[.](#3.sentence-1)
These operations play a special role in making
assignments in one thread visible to another[.](#3.sentence-2)
A synchronization operation on one
or more memory locations is either an acquire operation, a
release operation, or both an acquire and release operation[.](#3.sentence-3)
A synchronization
operation without an associated memory location is a fence and can be either an
acquire fence, a release fence, or both an acquire and release fence[.](#3.sentence-4)
In
addition, there are relaxed atomic operations, which are not synchronization
operations, and atomic read-modify-write operations, which have special
characteristics[.](#3.sentence-5)
[*Note [3](#note-3)*:
For example, a call that acquires a mutex will
perform an acquire operation on the locations comprising the mutex[.](#3.sentence-6)
Correspondingly, a call that releases the same mutex will perform a release
operation on those same locations[.](#3.sentence-7)
Informally, performing a release operation onA forces priorside effects on other memory locations to become visible
to other threads that later perform a consume or an acquire operation onA[.](#3.sentence-8)
“Relaxed” atomic operations are not synchronization operations even
though, like synchronization operations, they cannot contribute to data races[.](#3.sentence-9)
— *end note*]
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6664)
All modifications to a particular atomic object M occur in some
particular total order, called the [*modification order*](#def:modification_order "6.10.2.2Data races[intro.races]") of M[.](#4.sentence-1)
[*Note [4](#note-4)*:
There is a separate order for each
atomic object[.](#4.sentence-2)
There is no requirement that these can be combined into a single
total order for all objects[.](#4.sentence-3)
In general this will be impossible since different
threads can observe modifications to different objects in inconsistent orders[.](#4.sentence-4)
— *end note*]
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6674)
A [*release sequence*](#def:release_sequence "6.10.2.2Data races[intro.races]") headed
by a release operation A on an atomic object M is a maximal contiguous sub-sequence ofside effects in the modification order of M,
where the first operation is A, and
every subsequent operation is an atomic read-modify-write operation[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6683)
Certain library calls [*synchronize with*](#def:synchronize_with "6.10.2.2Data races[intro.races]") other library calls performed by
another thread[.](#6.sentence-1)
For example, an atomic store-release synchronizes with a
load-acquire that takes its value from the store ([[atomics.order]](atomics.order "32.5.4Order and consistency"))[.](#6.sentence-2)
[*Note [5](#note-5)*:
Except in the specified cases, reading a later value does not
necessarily ensure visibility as described below[.](#6.sentence-3)
Such a requirement would
sometimes interfere with efficient implementation[.](#6.sentence-4)
— *end note*]
[*Note [6](#note-6)*:
The
specifications of the synchronization operations define when one reads the value
written by another[.](#6.sentence-5)
For atomic objects, the definition is clear[.](#6.sentence-6)
All operations
on a given mutex occur in a single total order[.](#6.sentence-7)
Each mutex acquisition “reads
the value written” by the last mutex release[.](#6.sentence-8)
— *end note*]
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6700)
An evaluation A [*happens before*](#def:happens_before "6.10.2.2Data races[intro.races]") an evaluation B (or, equivalently, B happens after A)
if either
- [(7.1)](#7.1)
A is sequenced before B, or
- [(7.2)](#7.2)
A synchronizes with B, or
- [(7.3)](#7.3)
A happens before X and X happens before B[.](#7.sentence-1)
[*Note [7](#note-7)*:
An evaluation does not happen before itself[.](#7.sentence-2)
— *end note*]
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6713)
An evaluation A [*strongly happens before*](#def:strongly_happens_before "6.10.2.2Data races[intro.races]") an evaluation D if, either
- [(8.1)](#8.1)
A is sequenced before D, or
- [(8.2)](#8.2)
A synchronizes with D, and
both A and D are
sequentially consistent atomic operations ([[atomics.order]](atomics.order "32.5.4Order and consistency")), or
- [(8.3)](#8.3)
there are evaluations B and C such that A is sequenced before B,B happens before C, andC is sequenced before D, or
- [(8.4)](#8.4)
there is an evaluation B such thatA strongly happens before B, andB strongly happens before D[.](#8.sentence-1)
[*Note [8](#note-8)*:
Informally, if A strongly happens before B,
then A appears to be evaluated before B in all contexts[.](#8.sentence-2)
— *end note*]
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6735)
A [*visible side effect*](#def:side_effects,visible "6.10.2.2Data races[intro.races]") A on a scalar object or bit-field M with respect to a value computation B of M satisfies the
conditions:
- [(9.1)](#9.1)
A happens before B and
- [(9.2)](#9.2)
there is no otherside effect X to M such that A happens before X and X happens before B[.](#9.sentence-1)
The value of a non-atomic scalar object or bit-field M, as determined by
evaluation B, is the value stored by thevisible side effect A[.](#9.sentence-2)
[*Note [9](#note-9)*:
If there is ambiguity about which side effect to a
non-atomic object or bit-field is visible, then the behavior is either
unspecified or undefined[.](#9.sentence-3)
— *end note*]
[*Note [10](#note-10)*:
This states that operations on
ordinary objects are not visibly reordered[.](#9.sentence-4)
This is not actually detectable
without data races, but is needed to ensure that data races, as defined
below, and with suitable restrictions on the use of atomics, correspond to data
races in a simple interleaved (sequentially consistent) execution[.](#9.sentence-5)
— *end note*]
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6764)
The value of an
atomic object M, as determined by evaluation B, is the value
stored by some unspecified
side effect A that modifies M, where B does not happen
before A[.](#10.sentence-1)
[*Note [11](#note-11)*:
The set of such side effects is also restricted by the rest of the rules
described here, and in particular, by the coherence requirements below[.](#10.sentence-2)
— *end note*]
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6775)
If an operation A that modifies an atomic object M happens before
an operation B that modifies M, then A is earlier
than B in the modification order of M[.](#11.sentence-1)
[*Note [12](#note-12)*:
This requirement is known as write-write coherence[.](#11.sentence-2)
— *end note*]
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6784)
If avalue computation A of an atomic object M happens before a
value computation B of M, and A takes its value from a side
effect X on M, then the value computed by B is either
the value stored by X or the value stored by aside effect Y on M,
where Y follows X in the modification order of M[.](#12.sentence-1)
[*Note [13](#note-13)*:
This requirement is known as read-read coherence[.](#12.sentence-2)
— *end note*]
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6799)
If avalue computation A of an atomic object M happens before an
operation B that modifies M, then A takes its value from a side
effect X on M, where X precedes B in the
modification order of M[.](#13.sentence-1)
[*Note [14](#note-14)*:
This requirement is known as
read-write coherence[.](#13.sentence-2)
— *end note*]
[14](#14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6812)
If aside effect X on an atomic object M happens before a value
computation B of M, then the evaluation B takes its
value from X or from aside effect Y that follows X in the modification order of M[.](#14.sentence-1)
[*Note [15](#note-15)*:
This requirement is known as write-read coherence[.](#14.sentence-2)
— *end note*]
[15](#15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6825)
[*Note [16](#note-16)*:
The four preceding coherence requirements effectively disallow
compiler reordering of atomic operations to a single object, even if both
operations are relaxed loads[.](#15.sentence-1)
This effectively makes the cache coherence
guarantee provided by most hardware available to C++ atomic operations[.](#15.sentence-2)
— *end note*]
[16](#16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6833)
[*Note [17](#note-17)*:
The value observed by a load of an atomic depends on the “happens
before” relation, which depends on the values observed by loads of atomics[.](#16.sentence-1)
The intended reading is that there must exist an
association of atomic loads with modifications they observe that, together with
suitably chosen modification orders and the “happens before” relation derived
as described above, satisfy the resulting constraints as imposed here[.](#16.sentence-2)
— *end note*]
[17](#17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6843)
Two actions are [*potentially concurrent*](#def:potentially_concurrent "6.10.2.2Data races[intro.races]") if
- [(17.1)](#17.1)
they are performed by different threads, or
- [(17.2)](#17.2)
they are unsequenced, at least one is performed by a signal handler, and
they are not both performed by the same signal handler invocation[.](#17.sentence-1)
The execution of a program contains a [*data race*](#def:data_race "6.10.2.2Data races[intro.races]") if it contains two
potentially concurrent conflicting actions, at least one of which is not atomic,
and neither happens before the other,
except for the special case for signal handlers described below[.](#17.sentence-2)
Any such data race results in undefined
behavior[.](#17.sentence-3)
[*Note [18](#note-18)*:
It can be shown that programs that correctly use mutexes
and memory_order::seq_cst operations to prevent all data races and use no
other synchronization operations behave as if the operations executed by their
constituent threads were simply interleaved, with eachvalue computation of an
object being taken from the lastside effect on that object in that
interleaving[.](#17.sentence-4)
This is normally referred to as “sequential consistency”[.](#17.sentence-5)
However, this applies only to data-race-free programs, and data-race-free
programs cannot observe most program transformations that do not change
single-threaded program semantics[.](#17.sentence-6)
In fact, most single-threaded program
transformations remain possible, since any program that behaves
differently as a result has undefined behavior[.](#17.sentence-7)
— *end note*]
[18](#18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6874)
Two accesses to the same non-bit-field object
of type volatile std::sig_atomic_t do not
result in a data race if both occur in the same thread, even if one or more
occurs in a signal handler[.](#18.sentence-1)
For each signal handler invocation, evaluations
performed by the thread invoking a signal handler can be divided into two
groups A and B, such that no evaluations inB happen before evaluations in A, and the
evaluations of such volatile std::sig_atomic_t objects take values as though
all evaluations in A happened before the execution of the signal
handler and the execution of the signal handler happened before all evaluations
in B[.](#18.sentence-2)
[19](#19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6887)
[*Note [19](#note-19)*:
Compiler transformations that introduce assignments to a potentially
shared memory location that would not be modified by the abstract machine are
generally precluded by this document, since such an assignment might overwrite
another assignment by a different thread in cases in which an abstract machine
execution would not have encountered a data race[.](#19.sentence-1)
This includes implementations
of data member assignment that overwrite adjacent members in separate memory
locations[.](#19.sentence-2)
Reordering of atomic loads in cases in which the atomics in question
might alias is also generally precluded, since this could violate the coherence
rules[.](#19.sentence-3)
— *end note*]
[20](#20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6900)
[*Note [20](#note-20)*:
It is possible that transformations that introduce a speculative read of a potentially
shared memory location do not preserve the semantics of the C++ program as
defined in this document, since they potentially introduce a data race[.](#20.sentence-1)
However,
they are typically valid in the context of an optimizing compiler that targets a
specific machine with well-defined semantics for data races[.](#20.sentence-2)
They would be
invalid for a hypothetical machine that is not tolerant of races or provides
hardware race detection[.](#20.sentence-3)
— *end note*]

View File

@@ -0,0 +1,45 @@
[intro.structure]
# 4 General principles [[intro]](./#intro)
## 4.2 Structure of this document [intro.structure]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L1045)
[[lex]](lex "5Lexical conventions") through [[cpp]](cpp "15Preprocessing directives") describe the C++ programming
language[.](#1.sentence-1)
That description includes detailed syntactic specifications in
a form described in [[syntax]](syntax "4.3Syntax notation")[.](#1.sentence-2)
For convenience, [[gram]](gram "Annex A(informative)Grammar summary") repeats all such syntactic specifications[.](#1.sentence-3)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L1053)
[[support]](support "17Language support library") through [[exec]](exec "33Execution control library") and [[depr]](depr "Annex D(normative)Compatibility features") (the [*library clauses*](#def:library_clauses "4.2Structure of this document[intro.structure]")) describe the C++ standard library[.](#2.sentence-1)
That description includes detailed descriptions of the
entities and macros
that constitute the library, in a form described in [[library]](library "16Library introduction")[.](#2.sentence-2)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L1060)
[[implimits]](implimits "Annex B(informative)Implementation quantities") recommends lower bounds on the capacity of conforming
implementations[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/intro.tex#L1064)
[[diff]](diff "Annex C(informative)Compatibility") summarizes the evolution of C++ since its first
published description, and explains in detail the differences between
C++ and C[.](#4.sentence-1)
Certain features of C++ exist solely for compatibility
purposes; [[depr]](depr "Annex D(normative)Compatibility features") describes those features[.](#4.sentence-2)