Init
This commit is contained in:
181
cppdraft/intro/abstract.md
Normal file
181
cppdraft/intro/abstract.md
Normal 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.3 Function 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.2 Abstract machine [intro.abstract]")[.](#5.sentence-1)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
A call to std::observable_checkpoint ([[utility.undefined]](utility.undefined "22.2.9 Undefined behavior"))
|
||||
is an observable checkpoint,
|
||||
as are certain parts of
|
||||
the evaluation of contract assertions ([[basic.contract]](basic.contract "6.11 Contract 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.2 Abstract 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.2 Data 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.2 Abstract 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.1 Header <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.1 General")[.](#footnote-6.sentence-2)
|
||||
390
cppdraft/intro/compliance.md
Normal file
390
cppdraft/intro/compliance.md
Normal 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.1 General [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 "5 Lexical conventions") through [[exec]](exec "33 Execution 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.9 Diagnostic 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.2 Evaluation"))
|
||||
evaluated with a checking semantic
|
||||
in a manifestly constant-evaluated context ([[expr.const]](expr.const "7.7 Constant 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.3 Template 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.9 Diagnostic directives")),
|
||||
|
||||
- [(2.5)](#general-2.5)
|
||||
|
||||
a translation unit with
|
||||
a [*static_assert-declaration*](dcl.pre#nt:static_assert-declaration "9.1 Preamble [dcl.pre]") that fails ([[dcl.pre]](dcl.pre "9.1 Preamble")), or
|
||||
|
||||
- [(2.6)](#general-2.6)
|
||||
|
||||
a contract assertion evaluated with a terminating semantic ([[basic.contract.eval]](basic.contract.eval "6.11.2 Evaluation"))
|
||||
in a manifestly constant-evaluated context ([[expr.const]](expr.const "7.7 Constant 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.8 Member 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.2 Phases 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.2 Headers"))[.](#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.7 Program 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.2 Phases 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.1 General [intro.compliance.general]") or a[*freestanding implementation*](#def:implementation,freestanding "4.1.1 General [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 "5 Lexical conventions") through [[cpp]](cpp "15 Preprocessing directives") and
|
||||
the subset of the library facilities described in [[compliance]](compliance "16.4.2.5 Freestanding 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.1 General [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.4 Detailed 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 "2 Normative 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 "3 Terms and definitions") and [[intro.execution]](intro.execution "6.10.1 Sequential 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.2 Abstract 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.3 Function 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.2 Abstract 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.9 Undefined behavior"))
|
||||
is an observable checkpoint,
|
||||
as are certain parts of
|
||||
the evaluation of contract assertions ([[basic.contract]](basic.contract "6.11 Contract 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.2 Abstract 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.2 Data 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.2 Abstract 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.1 Header <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.1 General")[.](#footnote-6.sentence-2)
|
||||
214
cppdraft/intro/compliance/general.md
Normal file
214
cppdraft/intro/compliance/general.md
Normal 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.1 General [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 "5 Lexical conventions") through [[exec]](exec "33 Execution 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.9 Diagnostic 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.2 Evaluation"))
|
||||
evaluated with a checking semantic
|
||||
in a manifestly constant-evaluated context ([[expr.const]](expr.const "7.7 Constant 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.3 Template 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.9 Diagnostic directives")),
|
||||
|
||||
- [(2.5)](#2.5)
|
||||
|
||||
a translation unit with
|
||||
a [*static_assert-declaration*](dcl.pre#nt:static_assert-declaration "9.1 Preamble [dcl.pre]") that fails ([[dcl.pre]](dcl.pre "9.1 Preamble")), or
|
||||
|
||||
- [(2.6)](#2.6)
|
||||
|
||||
a contract assertion evaluated with a terminating semantic ([[basic.contract.eval]](basic.contract.eval "6.11.2 Evaluation"))
|
||||
in a manifestly constant-evaluated context ([[expr.const]](expr.const "7.7 Constant 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.8 Member 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.2 Phases 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.2 Headers"))[.](#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.7 Program 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.2 Phases 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.1 General [intro.compliance.general]") or a[*freestanding implementation*](#def:implementation,freestanding "4.1.1 General [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 "5 Lexical conventions") through [[cpp]](cpp "15 Preprocessing directives") and
|
||||
the subset of the library facilities described in [[compliance]](compliance "16.4.2.5 Freestanding 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.1 General [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.4 Detailed 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 "2 Normative 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 "3 Terms and definitions") and [[intro.execution]](intro.execution "6.10.1 Sequential 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.2 Abstract machine")[.](#footnote-4.sentence-1)
|
||||
419
cppdraft/intro/execution.md
Normal file
419
cppdraft/intro/execution.md
Normal file
@@ -0,0 +1,419 @@
|
||||
[intro.execution]
|
||||
|
||||
# 6 Basics [[basic]](./#basic)
|
||||
|
||||
## 6.10 Program execution [[basic.exec]](basic.exec#intro.execution)
|
||||
|
||||
### 6.10.1 Sequential execution [intro.execution]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6225)
|
||||
|
||||
An instance of each object with [automatic storage
|
||||
duration](basic.stc.auto "6.8.6.4 Automatic storage duration [basic.stc.auto]") is associated with each entry into its
|
||||
block[.](#1.sentence-1)
|
||||
|
||||
Such an object exists and retains its last-stored value during
|
||||
the execution of the block and while the block is suspended (by a call
|
||||
of a function, suspension of a coroutine ([[expr.await]](expr.await "7.6.2.4 Await")), or receipt of a signal)[.](#1.sentence-2)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6232)
|
||||
|
||||
A [*constituent expression*](#def:constituent_expression "6.10.1 Sequential execution [intro.execution]") is defined as follows:
|
||||
|
||||
- [(2.1)](#2.1)
|
||||
|
||||
The constituent expression of an expression is that expression[.](#2.1.sentence-1)
|
||||
|
||||
- [(2.2)](#2.2)
|
||||
|
||||
The constituent expression of a conversion is
|
||||
the corresponding implicit function call, if any, or
|
||||
the converted expression otherwise[.](#2.2.sentence-1)
|
||||
|
||||
- [(2.3)](#2.3)
|
||||
|
||||
The constituent expressions of a [*braced-init-list*](dcl.init.general#nt:braced-init-list "9.5.1 General [dcl.init.general]") or
|
||||
of a (possibly parenthesized) [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1 General [expr.post.general]") are the constituent expressions of the elements of the respective list[.](#2.3.sentence-1)
|
||||
|
||||
- [(2.4)](#2.4)
|
||||
|
||||
The constituent expressions of a [*brace-or-equal-initializer*](dcl.init.general#nt:brace-or-equal-initializer "9.5.1 General [dcl.init.general]") of the form = [*initializer-clause*](dcl.init.general#nt:initializer-clause "9.5.1 General [dcl.init.general]") are the constituent expressions of the [*initializer-clause*](dcl.init.general#nt:initializer-clause "9.5.1 General [dcl.init.general]")[.](#2.4.sentence-1)
|
||||
|
||||
[*Example [1](#example-1)*: struct A { int x; };struct B { int y; struct A a; };
|
||||
B b = { 5, { 1+1 } };
|
||||
|
||||
The constituent expressions of the [*initializer*](dcl.init.general#nt:initializer "9.5.1 General [dcl.init.general]") used for the initialization of b are 5 and 1+1[.](#2.sentence-2)
|
||||
|
||||
â *end example*]
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6260)
|
||||
|
||||
The [*immediate subexpressions*](#def:immediate_subexpression "6.10.1 Sequential execution [intro.execution]") of an expression E are
|
||||
|
||||
- [(3.1)](#3.1)
|
||||
|
||||
the constituent expressions of E's operands ([[expr.prop]](expr.prop "7.2 Properties of expressions")),
|
||||
|
||||
- [(3.2)](#3.2)
|
||||
|
||||
any function call that E implicitly invokes,
|
||||
|
||||
- [(3.3)](#3.3)
|
||||
|
||||
if E is a [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") ([[expr.prim.lambda]](expr.prim.lambda "7.5.6 Lambda expressions")),
|
||||
the initialization of the entities captured by copy and
|
||||
the constituent expressions of the [*initializer*](dcl.init.general#nt:initializer "9.5.1 General [dcl.init.general]") of the [*init-capture*](expr.prim.lambda.capture#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]")*s*,
|
||||
|
||||
- [(3.4)](#3.4)
|
||||
|
||||
if E is a [function call](expr.call "7.6.1.3 Function call [expr.call]") or implicitly invokes a function,
|
||||
the constituent expressions of each default argument ([[dcl.fct.default]](dcl.fct.default "9.3.4.7 Default arguments"))
|
||||
used in the call, or
|
||||
|
||||
- [(3.5)](#3.5)
|
||||
|
||||
if E creates an aggregate object ([[dcl.init.aggr]](dcl.init.aggr "9.5.2 Aggregates")),
|
||||
the constituent expressions of each default member initializer ([[class.mem]](class.mem "11.4 Class members"))
|
||||
used in the initialization[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6281)
|
||||
|
||||
A [*subexpression*](#def:subexpression "6.10.1 Sequential execution [intro.execution]") of an expression E is
|
||||
an immediate subexpression of E or
|
||||
a subexpression of an immediate subexpression of E[.](#4.sentence-1)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
Expressions appearing in the [*compound-statement*](stmt.block#nt:compound-statement "8.4 Compound statement or block [stmt.block]") of a [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") are not subexpressions of the [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]")[.](#4.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
The [*potentially-evaluated subexpressions*](#def:subexpression,potentially-evaluated "6.10.1 Sequential execution [intro.execution]") of
|
||||
an expression, conversion, or [*initializer*](dcl.init.general#nt:initializer "9.5.1 General [dcl.init.general]") E are
|
||||
|
||||
- [(4.1)](#4.1)
|
||||
|
||||
the constituent expressions of E and
|
||||
|
||||
- [(4.2)](#4.2)
|
||||
|
||||
the subexpressions thereof that
|
||||
are not subexpressions of a nested unevaluated operand ([[expr.context]](expr.context#term.unevaluated.operand "7.2.3 Context dependence"))[.](#4.sentence-3)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6299)
|
||||
|
||||
A [*full-expression*](#def:full-expression "6.10.1 Sequential execution [intro.execution]") is
|
||||
|
||||
- [(5.1)](#5.1)
|
||||
|
||||
an [unevaluated operand](expr.context#def:unevaluated_operand "7.2.3 Context dependence [expr.context]"),
|
||||
|
||||
- [(5.2)](#5.2)
|
||||
|
||||
a [*constant-expression*](expr.const#nt:constant-expression "7.7 Constant expressions [expr.const]") ([[expr.const]](expr.const "7.7 Constant expressions")),
|
||||
|
||||
- [(5.3)](#5.3)
|
||||
|
||||
an immediate invocation ([[expr.const]](expr.const "7.7 Constant expressions")),
|
||||
|
||||
- [(5.4)](#5.4)
|
||||
|
||||
an [*init-declarator*](dcl.decl.general#nt:init-declarator "9.3.1 General [dcl.decl.general]") ([[dcl.decl]](dcl.decl "9.3 Declarators"))
|
||||
(including such introduced by a structured binding ([[dcl.struct.bind]](dcl.struct.bind "9.7 Structured binding declarations"))) or
|
||||
a [*mem-initializer*](class.base.init#nt:mem-initializer "11.9.3 Initializing bases and members [class.base.init]") ([[class.base.init]](class.base.init "11.9.3 Initializing bases and members")),
|
||||
including the constituent expressions of the initializer,
|
||||
|
||||
- [(5.5)](#5.5)
|
||||
|
||||
an invocation of a destructor generated at the end of the lifetime
|
||||
of an object other than a temporary object ([[class.temporary]](class.temporary "6.8.7 Temporary objects"))
|
||||
whose lifetime has not been extended,
|
||||
|
||||
- [(5.6)](#5.6)
|
||||
|
||||
the predicate of a contract assertion ([[basic.contract]](basic.contract "6.11 Contract assertions")), or
|
||||
|
||||
- [(5.7)](#5.7)
|
||||
|
||||
an expression that is not a subexpression of another expression and
|
||||
that is not otherwise part of a full-expression[.](#5.sentence-1)
|
||||
|
||||
If a language construct is defined to produce an implicit call of a function,
|
||||
a use of the language construct is considered to be an expression
|
||||
for the purposes of this definition[.](#5.sentence-2)
|
||||
|
||||
Conversions applied to the result of an expression in order to satisfy the requirements
|
||||
of the language construct in which the expression appears
|
||||
are also considered to be part of the full-expression[.](#5.sentence-3)
|
||||
|
||||
For an initializer, performing the initialization of the entity
|
||||
(including evaluating default member initializers of an aggregate)
|
||||
is also considered part of the full-expression[.](#5.sentence-4)
|
||||
|
||||
[*Example [2](#example-2)*: struct S { S(int i): I(i) { } // full-expression is initialization of Iint& v() { return I; }~S() noexcept(false) { }private:int I;};
|
||||
|
||||
S s1(1); // full-expression comprises call of S::S(int)void f() { S s2 = 2; // full-expression comprises call of S::S(int)if (S(3).v()) // full-expression includes lvalue-to-rvalue and int to bool conversions,// performed before temporary is deleted at end of full-expression{ }bool b = noexcept(S(4)); // exception specification of destructor of S considered for noexcept// full-expression is destruction of s2 at end of block}struct B { B(S = S(0));};
|
||||
B b[2] = { B(), B() }; // full-expression is the entire initialization// including the destruction of temporaries â *end example*]
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6360)
|
||||
|
||||
[*Note [2](#note-2)*:
|
||||
|
||||
The evaluation of a full-expression can include the
|
||||
evaluation of subexpressions that are not lexically part of the
|
||||
full-expression[.](#6.sentence-1)
|
||||
|
||||
For example, subexpressions involved in evaluating
|
||||
default arguments ([[dcl.fct.default]](dcl.fct.default "9.3.4.7 Default arguments")) are considered to
|
||||
be created in the expression that calls the function, not the expression
|
||||
that defines the default argument[.](#6.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6370)
|
||||
|
||||
Reading an object designated by a volatile glvalue ([[basic.lval]](basic.lval "7.2.1 Value category")),
|
||||
modifying an object,
|
||||
producing an injected declaration ([[expr.const]](expr.const "7.7 Constant expressions")),
|
||||
calling a library I/O function, or
|
||||
calling a function that does any of those operations
|
||||
are all [*side effects*](#def:side_effects "6.10.1 Sequential execution [intro.execution]"),
|
||||
which are changes in the state of the execution or translation environment[.](#7.sentence-1)
|
||||
|
||||
[*Evaluation*](#def:evaluation "6.10.1 Sequential execution [intro.execution]") of an expression (or a
|
||||
subexpression) in general includes both value computations (including
|
||||
determining the identity of an object for glvalue evaluation and fetching
|
||||
a value previously assigned to an object for prvalue evaluation) and
|
||||
initiation of side effects[.](#7.sentence-2)
|
||||
|
||||
When a call to a library I/O function
|
||||
returns or an access through a volatile glvalue is evaluated, the side
|
||||
effect is considered complete, even though some external actions implied
|
||||
by the call (such as the I/O itself) or by the volatile access
|
||||
may not have completed yet[.](#7.sentence-3)
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6389)
|
||||
|
||||
[*Sequenced before*](#def:sequenced_before "6.10.1 Sequential execution [intro.execution]") is an asymmetric, transitive, pair-wise relation between
|
||||
evaluations executed by a single thread ([[intro.multithread]](intro.multithread "6.10.2 Multi-threaded executions and data races")), which induces
|
||||
a partial order among those evaluations[.](#8.sentence-1)
|
||||
|
||||
Given any two evaluations *A* and*B*, if *A* is sequenced before *B* (or, equivalently, *B* is [*sequenced after*](#def:sequenced_after "6.10.1 Sequential execution [intro.execution]") *A*),
|
||||
then the execution of*A* shall precede the execution of *B*[.](#8.sentence-2)
|
||||
|
||||
If *A* is not sequenced
|
||||
before *B* and *B* is not sequenced before *A*, then *A* and*B* are [*unsequenced*](#def:unsequenced "6.10.1 Sequential execution [intro.execution]")[.](#8.sentence-3)
|
||||
|
||||
[*Note [3](#note-3)*:
|
||||
|
||||
The execution of unsequenced
|
||||
evaluations can overlap[.](#8.sentence-4)
|
||||
|
||||
â *end note*]
|
||||
|
||||
Evaluations *A* and *B* are[*indeterminately sequenced*](#def:indeterminately_sequenced "6.10.1 Sequential execution [intro.execution]") when either *A* is sequenced before*B* or *B* is sequenced before *A*, but it is unspecified which[.](#8.sentence-5)
|
||||
|
||||
[*Note [4](#note-4)*:
|
||||
|
||||
Indeterminately sequenced evaluations cannot overlap, but either
|
||||
can be executed first[.](#8.sentence-6)
|
||||
|
||||
â *end note*]
|
||||
|
||||
An expression *X* is said to be sequenced before
|
||||
an expression *Y* if
|
||||
every value computation and every side effect
|
||||
associated with the expression *X* is sequenced before
|
||||
every value computation and every side effect
|
||||
associated with the expression *Y*[.](#8.sentence-7)
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6419)
|
||||
|
||||
Everyvalue computation andside effect associated with a full-expression is
|
||||
sequenced before every value computation and side effect associated with the
|
||||
next full-expression to be evaluated[.](#9.sentence-1)[35](#footnote-35 "As specified in [class.temporary], after a full-expression is evaluated, a sequence of zero or more invocations of destructor functions for temporary objects takes place, usually in reverse order of the construction of each temporary object.")
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6434)
|
||||
|
||||
Except where noted, evaluations of operands of individual operators and
|
||||
of subexpressions of individual expressions are unsequenced[.](#10.sentence-1)
|
||||
|
||||
[*Note [5](#note-5)*:
|
||||
|
||||
In an expression that is evaluated more than once during the execution
|
||||
of a program, unsequenced and indeterminately sequenced evaluations of
|
||||
its subexpressions need not be performed consistently in different
|
||||
evaluations[.](#10.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
The value computations of the operands of an
|
||||
operator are sequenced before the value computation of the result of the
|
||||
operator[.](#10.sentence-3)
|
||||
|
||||
The behavior is undefined if
|
||||
|
||||
- [(10.1)](#10.1)
|
||||
|
||||
a side effect on a memory location ([[intro.memory]](intro.memory "6.8.1 Memory model")) or
|
||||
|
||||
- [(10.2)](#10.2)
|
||||
|
||||
starting or ending the lifetime of an object in a memory location
|
||||
|
||||
is unsequenced relative to
|
||||
|
||||
- [(10.3)](#10.3)
|
||||
|
||||
another side effect on the same memory location,
|
||||
|
||||
- [(10.4)](#10.4)
|
||||
|
||||
starting or ending the lifetime of an object occupying storage that
|
||||
overlaps with the memory location, or
|
||||
|
||||
- [(10.5)](#10.5)
|
||||
|
||||
a value computation using the value of any object in the same memory location,
|
||||
|
||||
and the two evaluations are not potentially concurrent ([[intro.multithread]](intro.multithread "6.10.2 Multi-threaded executions and data races"))[.](#10.sentence-4)
|
||||
|
||||
[*Note [6](#note-6)*:
|
||||
|
||||
Starting the lifetime of an object in a memory location can end the lifetime of
|
||||
objects in other memory locations ([[basic.life]](basic.life "6.8.4 Lifetime"))[.](#10.sentence-5)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[*Note [7](#note-7)*:
|
||||
|
||||
The next subclause imposes similar, but more complex restrictions on
|
||||
potentially concurrent computations[.](#10.sentence-6)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[*Example [3](#example-3)*: void g(int i) { i = 7, i++, i++; // i becomes 9 i = i++ + 1; // the value of i is incremented i = i++ + i; // undefined behavior i = i + 1; // the value of i is incrementedunion U { int x, y; } u; (u.x = 1, 0) + (u.y = 2, 0); // undefined behavior} â *end example*]
|
||||
|
||||
[11](#11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6490)
|
||||
|
||||
When invoking a function *f* (whether or not the function is inline),
|
||||
every argument expression and
|
||||
the postfix expression designating *f* are sequenced before
|
||||
every precondition assertion of *f* ([[dcl.contract.func]](dcl.contract.func "9.4.1 General")),
|
||||
which in turn are sequenced before
|
||||
every expression or statement
|
||||
in the body of *f*,
|
||||
which in turn are sequenced before
|
||||
every postcondition assertion of *f*[.](#11.sentence-1)
|
||||
|
||||
[12](#12)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6502)
|
||||
|
||||
For each
|
||||
|
||||
- [(12.1)](#12.1)
|
||||
|
||||
function invocation,
|
||||
|
||||
- [(12.2)](#12.2)
|
||||
|
||||
evaluation of an [*await-expression*](expr.await#nt:await-expression "7.6.2.4 Await [expr.await]") ([[expr.await]](expr.await "7.6.2.4 Await")), or
|
||||
|
||||
- [(12.3)](#12.3)
|
||||
|
||||
evaluation of a [*throw-expression*](expr.throw#nt:throw-expression "7.6.18 Throwing an exception [expr.throw]") ([[expr.throw]](expr.throw "7.6.18 Throwing an exception"))
|
||||
|
||||
*F*,
|
||||
each evaluation that does not occur within *F* but is evaluated on the same thread and as part of the same signal handler (if any)
|
||||
is either sequenced before all evaluations that occur within *F* or sequenced after all evaluations that occur within *F*;[36](#footnote-36 "In other words, function executions do not interleave with each other.") if *F* invokes or resumes a coroutine ([[expr.await]](expr.await "7.6.2.4 Await")),
|
||||
only evaluations
|
||||
subsequent to the previous suspension (if any) and
|
||||
prior to the next suspension (if any)
|
||||
are considered to occur within *F*[.](#12.sentence-1)
|
||||
|
||||
[13](#13)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6524)
|
||||
|
||||
Several contexts in C++ cause evaluation of a function call, even
|
||||
though no corresponding function call syntax appears in the translation
|
||||
unit[.](#13.sentence-1)
|
||||
|
||||
[*Example [4](#example-4)*:
|
||||
|
||||
Evaluation of a [*new-expression*](expr.new#nt:new-expression "7.6.2.8 New [expr.new]") invokes one or more allocation
|
||||
and constructor functions; see [[expr.new]](expr.new "7.6.2.8 New")[.](#13.sentence-2)
|
||||
|
||||
For another example,
|
||||
invocation of a conversion function ([[class.conv.fct]](class.conv.fct "11.4.8.3 Conversion functions")) can arise in
|
||||
contexts in which no function call syntax appears[.](#13.sentence-3)
|
||||
|
||||
â *end example*]
|
||||
|
||||
[14](#14)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6535)
|
||||
|
||||
The sequencing constraints on the execution of the called function (as
|
||||
described above) are features of the function calls as evaluated,
|
||||
regardless of the syntax of the expression that calls the function[.](#14.sentence-1)
|
||||
|
||||
[15](#15)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6543)
|
||||
|
||||
If a signal handler is executed as a result of a call to the std::raise function, then the execution of the handler is sequenced after the invocation
|
||||
of the std::raise function and before its return[.](#15.sentence-1)
|
||||
|
||||
[*Note [8](#note-8)*:
|
||||
|
||||
When a signal is received for another reason, the execution of the
|
||||
signal handler is usually unsequenced with respect to the rest of the program[.](#15.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[16](#16)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6552)
|
||||
|
||||
During the evaluation of an expression
|
||||
as a core constant expression ([[expr.const]](expr.const "7.7 Constant expressions")),
|
||||
evaluations of operands of individual operators and
|
||||
of subexpressions of individual expressions
|
||||
that are otherwise either unsequenced or indeterminately sequenced
|
||||
are evaluated in lexical order[.](#16.sentence-1)
|
||||
|
||||
[35)](#footnote-35)[35)](#footnoteref-35)
|
||||
|
||||
As specified
|
||||
in [[class.temporary]](class.temporary "6.8.7 Temporary objects"), after a full-expression is evaluated, a sequence of
|
||||
zero or more invocations of destructor functions for temporary objects takes
|
||||
place, usually in reverse order of the construction of each temporary object[.](#footnote-35.sentence-1)
|
||||
|
||||
[36)](#footnote-36)[36)](#footnoteref-36)
|
||||
|
||||
In other words,
|
||||
function executions do not interleave with each other[.](#footnote-36.sentence-1)
|
||||
100
cppdraft/intro/memory.md
Normal file
100
cppdraft/intro/memory.md
Normal 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.1 Memory 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.1 Character 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.1 General")[.](#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.1 Memory 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.2 Multi-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.6 Header <climits> synopsis [climits.syn]")[.](#footnote-19.sentence-1)
|
||||
856
cppdraft/intro/multithread.md
Normal file
856
cppdraft/intro/multithread.md
Normal 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.1 General [intro.multithread.general]") (also known as a [*thread*](#def:thread "6.10.2.1 General [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.6 Storage 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.4 Compound 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.2 Data races [intro.races]") if one of them
|
||||
|
||||
- [(2.1)](#intro.races-2.1)
|
||||
|
||||
modifies ([[defns.access]](defns.access "3.1 access")) a memory location ([[intro.memory]](intro.memory "6.8.1 Memory 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.5 Atomic operations")) and
|
||||
operations on mutexes ([[thread]](thread "32 Concurrency 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.2 Data 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.2 Data 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.2 Data 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.4 Order 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.2 Data 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.2 Data 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.4 Order 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.2 Data 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.2 Data 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.2 Data 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.5 Namespace 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.4 Order and consistency")), or
|
||||
|
||||
- [(1.6)](#intro.progress-1.6)
|
||||
|
||||
continue execution of a trivial infinite loop ([[stmt.iter.general]](stmt.iter.general "8.6.1 General"))[.](#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.10 Flag type and operations"))
|
||||
or indicated as lock-free ([[atomics.lockfree]](atomics.lockfree "32.5.5 Lock-free property"))
|
||||
are [*lock-free executions*](#def:lock-free_execution "6.10.2.3 Forward 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.6 block"))
|
||||
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.3 Forward 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.4 Order 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.6 block"))
|
||||
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.3 Forward 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.3 Forward 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.1 main function")) and the threads of execution created bystd::thread ([[thread.thread.class]](thread.thread.class "32.4.3 Class thread"))
|
||||
or std::jthread ([[thread.jthread.class]](thread.jthread.class "32.4.4 Class 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.3 Forward 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.3 Forward 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.3 Forward 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)
|
||||
67
cppdraft/intro/multithread/general.md
Normal file
67
cppdraft/intro/multithread/general.md
Normal 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.1 General [intro.multithread.general]") (also known as a [*thread*](#def:thread "6.10.2.1 General [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.6 Storage 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.4 Compound types"))[.](#footnote-37.sentence-1)
|
||||
360
cppdraft/intro/object.md
Normal file
360
cppdraft/intro/object.md
Normal 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.2 Object model [intro.object]") is created
|
||||
by a [definition](basic.def "6.2 Declarations and definitions [basic.def]"),
|
||||
by a [*new-expression*](expr.new#nt:new-expression "7.6.2.8 New [expr.new]") ([[expr.new]](expr.new "7.6.2.8 New")),
|
||||
by an operation that implicitly creates objects (see below),
|
||||
when implicitly changing the active member of a [union](class.union "11.5 Unions [class.union]"),
|
||||
or
|
||||
when a temporary object is created ([[conv.rval]](conv.rval "7.3.5 Temporary materialization conversion"), [[class.temporary]](class.temporary "6.8.7 Temporary objects"))[.](#1.sentence-2)
|
||||
|
||||
An object occupies a region of storage
|
||||
in its period of construction ([[class.cdtor]](class.cdtor "11.9.5 Construction and destruction")),
|
||||
throughout its [lifetime](basic.life "6.8.4 Lifetime [basic.life]"),
|
||||
and
|
||||
in its period of destruction ([[class.cdtor]](class.cdtor "11.9.5 Construction 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.1 Preamble"))[.](#1.sentence-6)
|
||||
|
||||
An object has a storage
|
||||
duration ([[basic.stc]](basic.stc "6.8.6 Storage duration")) which influences its
|
||||
lifetime ([[basic.life]](basic.life "6.8.4 Lifetime"))[.](#1.sentence-7)
|
||||
|
||||
An object has a
|
||||
type ([[basic.types]](basic.types "6.9 Types"))[.](#1.sentence-8)
|
||||
|
||||
[*Note [2](#note-2)*:
|
||||
|
||||
Some objects are
|
||||
polymorphic ([[class.virtual]](class.virtual "11.7.3 Virtual 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.2 Object model [intro.object]")[.](#2.sentence-1)
|
||||
|
||||
A subobject can be
|
||||
a [*member subobject*](#def:member_subobject "6.8.2 Object model [intro.object]") ([[class.mem]](class.mem "11.4 Class members")), a [*base class subobject*](#def:base_class_subobject "6.8.2 Object model [intro.object]") ([[class.derived]](class.derived "11.7 Derived 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.2 Object 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.8 New"))
|
||||
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.1 Header <cstddef> synopsis")),
|
||||
that array [*provides storage*](#def:provides_storage "6.8.2 Object 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.4 Lifetime"))[.](#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.2 Object 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.2 Object 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.2 Object 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.2 Object 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.2 Object 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.11 No 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.10 Bit-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.1 General")) 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.2 Object model [intro.object]") if it is
|
||||
|
||||
- [(9.1)](#9.1)
|
||||
|
||||
a string literal object ([[lex.string]](lex.string "5.13.5 String literals")),
|
||||
|
||||
- [(9.2)](#9.2)
|
||||
|
||||
the backing array of an initializer list ([[dcl.init.ref]](dcl.init.ref "9.5.4 References")), 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.15 Promoting 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.6 Qualification 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.2 Object 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.1 General"))
|
||||
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.2 Object 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.4 Compound 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.6 Explicit lifetime management"), [[c.malloc]](c.malloc "20.2.12 C library memory allocation"), [[mem.res.public]](mem.res.public "20.5.2.2 Public member functions"), [[bit.cast]](bit.cast "22.11.3 Function template bit_cast"), [[cstring.syn]](cstring.syn "27.5.1 Header <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.1 Sequential execution"))[.](#footnote-20.sentence-1)
|
||||
331
cppdraft/intro/progress.md
Normal file
331
cppdraft/intro/progress.md
Normal 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.5 Namespace 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.4 Order and consistency")), or
|
||||
|
||||
- [(1.6)](#1.6)
|
||||
|
||||
continue execution of a trivial infinite loop ([[stmt.iter.general]](stmt.iter.general "8.6.1 General"))[.](#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.10 Flag type and operations"))
|
||||
or indicated as lock-free ([[atomics.lockfree]](atomics.lockfree "32.5.5 Lock-free property"))
|
||||
are [*lock-free executions*](#def:lock-free_execution "6.10.2.3 Forward 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.6 block"))
|
||||
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.3 Forward 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.4 Order 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.6 block"))
|
||||
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.3 Forward 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.3 Forward 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.1 main function")) and the threads of execution created bystd::thread ([[thread.thread.class]](thread.thread.class "32.4.3 Class thread"))
|
||||
or std::jthread ([[thread.jthread.class]](thread.jthread.class "32.4.4 Class 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.3 Forward 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.3 Forward 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.3 Forward 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
472
cppdraft/intro/races.md
Normal 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.2 Data races [intro.races]") if one of them
|
||||
|
||||
- [(2.1)](#2.1)
|
||||
|
||||
modifies ([[defns.access]](defns.access "3.1 access")) a memory location ([[intro.memory]](intro.memory "6.8.1 Memory 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.5 Atomic operations")) and
|
||||
operations on mutexes ([[thread]](thread "32 Concurrency 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.2 Data 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.2 Data 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.2 Data 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.4 Order 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.2 Data 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.2 Data 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.4 Order 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.2 Data 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.2 Data 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.2 Data 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*]
|
||||
45
cppdraft/intro/structure.md
Normal file
45
cppdraft/intro/structure.md
Normal 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 "5 Lexical conventions") through [[cpp]](cpp "15 Preprocessing directives") describe the C++ programming
|
||||
language[.](#1.sentence-1)
|
||||
|
||||
That description includes detailed syntactic specifications in
|
||||
a form described in [[syntax]](syntax "4.3 Syntax 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 "17 Language support library") through [[exec]](exec "33 Execution control library") and [[depr]](depr "Annex D (normative) Compatibility features") (the [*library clauses*](#def:library_clauses "4.2 Structure 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 "16 Library 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)
|
||||
Reference in New Issue
Block a user