188 lines
7.3 KiB
Markdown
188 lines
7.3 KiB
Markdown
[basic.start.dynamic]
|
||
|
||
# 6 Basics [[basic]](./#basic)
|
||
|
||
## 6.10 Program execution [[basic.exec]](basic.exec#basic.start.dynamic)
|
||
|
||
### 6.10.3 Start and termination [[basic.start]](basic.start#dynamic)
|
||
|
||
#### 6.10.3.3 Dynamic initialization of non-block variables [basic.start.dynamic]
|
||
|
||
[1](#1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7302)
|
||
|
||
Dynamic initialization of a non-block variable with static storage duration is
|
||
unordered if the variable is an implicitly or explicitly instantiated
|
||
specialization, is partially-ordered if the variable
|
||
is an inline variable that is not an implicitly or explicitly instantiated
|
||
specialization, and otherwise is ordered[.](#1.sentence-1)
|
||
|
||
[*Note [1](#note-1)*:
|
||
|
||
A non-inline explicit specialization of a templated variable
|
||
has ordered initialization[.](#1.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[2](#2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7316)
|
||
|
||
A declaration D is[*appearance-ordered*](#def:appearance-ordered "6.10.3.3 Dynamic initialization of non-block variables [basic.start.dynamic]") before a declaration E if
|
||
|
||
- [(2.1)](#2.1)
|
||
|
||
D appears in the same translation unit as E, or
|
||
|
||
- [(2.2)](#2.2)
|
||
|
||
the translation unit containing E has an interface dependency on the translation unit containing D,
|
||
|
||
in either case prior to E[.](#2.sentence-1)
|
||
|
||
[3](#3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7326)
|
||
|
||
Dynamic initialization of non-block variables V and W with static storage duration are ordered as follows:
|
||
|
||
- [(3.1)](#3.1)
|
||
|
||
If V and W have ordered initialization and
|
||
the definition of V is appearance-ordered before the definition of W, or
|
||
if V has partially-ordered initialization,W does not have unordered initialization, and
|
||
for every definition E of W there exists a definition D of V such that D is appearance-ordered before E, then
|
||
* [(3.1.1)](#3.1.1)
|
||
|
||
if the program does not start a thread ([[intro.multithread]](intro.multithread "6.10.2 Multi-threaded executions and data races"))
|
||
other than the main thread ([[basic.start.main]](basic.start.main "6.10.3.1 main function"))
|
||
or V and W have ordered initialization and
|
||
they are defined in the same translation unit,
|
||
the initialization of V is sequenced before
|
||
the initialization of W;
|
||
|
||
* [(3.1.2)](#3.1.2)
|
||
|
||
otherwise,
|
||
the initialization of V strongly happens before
|
||
the initialization of W[.](#3.1.sentence-1)
|
||
|
||
- [(3.2)](#3.2)
|
||
|
||
Otherwise, if the program starts a thread
|
||
other than the main thread
|
||
before either V or W is initialized,
|
||
it is unspecified in which threads
|
||
the initializations of V and W occur;
|
||
the initializations are unsequenced if they occur in the same thread[.](#3.2.sentence-1)
|
||
|
||
- [(3.3)](#3.3)
|
||
|
||
Otherwise, the initializations of V and W are indeterminately sequenced[.](#3.3.sentence-1)
|
||
|
||
[*Note [2](#note-2)*:
|
||
|
||
This definition permits initialization of a sequence of
|
||
ordered variables concurrently with another sequence[.](#3.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[4](#4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7371)
|
||
|
||
A [*non-initialization odr-use*](#def:odr-use,non-initialization "6.10.3.3 Dynamic initialization of non-block variables [basic.start.dynamic]") is an odr-use ([[basic.def.odr]](basic.def.odr#term.odr.use "6.3 One-definition rule")) not caused directly or indirectly by
|
||
the initialization of a non-block static or thread storage duration variable[.](#4.sentence-1)
|
||
|
||
[5](#5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7377)
|
||
|
||
It is implementation-defined
|
||
whether the dynamic initialization of a
|
||
non-block non-inline variable with static storage duration
|
||
is sequenced before the first statement of main or is deferred[.](#5.sentence-1)
|
||
|
||
If it is deferred, it strongly happens before
|
||
any non-initialization odr-use
|
||
of any non-inline function or non-inline variable
|
||
defined in the same translation unit as the variable to be initialized[.](#5.sentence-2)[38](#footnote-38 "A non-block variable with static storage duration having initialization with side effects is initialized in this case, even if it is not itself odr-used ([term.odr.use], [basic.stc.static]).")
|
||
|
||
It is implementation-defined
|
||
in which threads and at which points in the program such deferred dynamic initialization occurs[.](#5.sentence-3)
|
||
|
||
*Recommended practice*: An implementation should choose such points in a way
|
||
that allows the programmer to avoid deadlocks[.](#5.sentence-4)
|
||
|
||
[*Example [1](#example-1)*: // - File 1 -#include "a.h"#include "b.h" B b;
|
||
A::A() { b.Use();}// - File 2 -#include "a.h" A a;
|
||
|
||
// - File 3 -#include "a.h"#include "b.h"extern A a;extern B b;
|
||
|
||
int main() { a.Use();
|
||
b.Use();}
|
||
|
||
It is implementation-defined
|
||
whether either a or b is
|
||
initialized before main is entered or whether the
|
||
initializations are delayed until a is first odr-used inmain[.](#5.sentence-5)
|
||
|
||
In particular, if a is initialized beforemain is entered, it is not guaranteed that b will be
|
||
initialized before it is odr-used by the initialization of a, that
|
||
is, before A::A is called[.](#5.sentence-6)
|
||
|
||
If, however, a is initialized
|
||
at some point after the first statement of main, b will
|
||
be initialized prior to its use in A::A[.](#5.sentence-7)
|
||
|
||
â *end example*]
|
||
|
||
[6](#6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7437)
|
||
|
||
It is implementation-defined
|
||
whether the dynamic initialization of a
|
||
non-block inline variable with static storage duration
|
||
is sequenced before the first statement of main or is deferred[.](#6.sentence-1)
|
||
|
||
If it is deferred, it strongly happens before
|
||
any non-initialization odr-use
|
||
of that variable[.](#6.sentence-2)
|
||
|
||
It is implementation-defined
|
||
in which threads and at which points in the program such deferred dynamic initialization occurs[.](#6.sentence-3)
|
||
|
||
[7](#7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7448)
|
||
|
||
It is implementation-defined
|
||
whether the dynamic initialization of a
|
||
non-block non-inline variable with thread storage duration
|
||
is sequenced before the first statement of the initial function of a thread or is deferred[.](#7.sentence-1)
|
||
|
||
If it is deferred,
|
||
the initialization associated with the entity for thread *t* is sequenced before the first non-initialization odr-use by *t* of any non-inline variable with thread storage duration
|
||
defined in the same translation unit as the variable to be initialized[.](#7.sentence-2)
|
||
|
||
It is implementation-defined
|
||
in which threads and at which points in the program such deferred dynamic initialization occurs[.](#7.sentence-3)
|
||
|
||
[8](#8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7461)
|
||
|
||
If the initialization of
|
||
a non-block variable with static or thread storage duration
|
||
exits via an exception,
|
||
the function std::terminate is called ([[except.terminate]](except.terminate "14.6.2 The std::terminate function"))[.](#8.sentence-1)
|
||
|
||
[38)](#footnote-38)[38)](#footnoteref-38)
|
||
|
||
A non-block variable with static storage duration
|
||
having initialization
|
||
with side effects is initialized in this case,
|
||
even if it is not itself odr-used ([[basic.def.odr]](basic.def.odr#term.odr.use "6.3 One-definition rule"), [[basic.stc.static]](basic.stc.static "6.8.6.2 Static storage duration"))[.](#footnote-38.sentence-1)
|