Files
2025-10-25 03:02:53 +03:00

188 lines
7.3 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[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.3Dynamic 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.2Multi-threaded executions and data races"))
other than the main thread ([[basic.start.main]](basic.start.main "6.10.3.1main 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.3Dynamic initialization of non-block variables[basic.start.dynamic]") is an odr-use ([[basic.def.odr]](basic.def.odr#term.odr.use "6.3One-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.2The 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.3One-definition rule"), [[basic.stc.static]](basic.stc.static "6.8.6.2Static storage duration"))[.](#footnote-38.sentence-1)