是否保证主要的全局初始化程序能够运行单线程?

dxi*_*xiv 6 c++ multithreading language-lawyer

例如,node::node()以下代码段中的构造函数访问全局变量node::count::tail没有任何多线程保护.C++标准是否保证输出始终是0 1 2(无论顺序如何)的排列?

#include <stdio.h>

struct node *tail;

struct node
{
    static int count;

    int index;
    node *prev;

    node()
    {   index = count++; prev = tail; tail = this; }
};

int node::count;

node one, two[2];

int main(int argc, char *argv[])
{
    for(node *p = tail; p; p = p->prev)
        printf("%d\n", p->index);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我正在寻找基于(适用)标准的答案,而不是针对实现或编译器特定行为.有许多对SO有关的问题,但它不是完全清楚他们是如何直接适用于这个特定的和相当基本情况(是C++中的静态成员变量的初始化是线程安全的?,是本地静态变量的初始化线程安全的C++ 11 ?等).

Igo*_*nik 5

只要程序本身不启动线程(例如在某个全局变量的构造函数中),全局变量的初始化就可以保证是单线程的.一旦发生这种情况,就可以在一定程度上实现剩余的初始化.

[basic.start.init]/2 ...在单个翻译单元中定义的有序初始化的变量应按其在翻译单元中的定义顺序进行初始化.如果程序启动一个线程(30.3),则对于在不同转换单元中定义的变量的初始化,变量的后续初始化是未序的.否则,对于在不同转换单元中定义的变量的初始化,变量的初始化是不确定地排序的.如果程序启动一个线程,则对于每个其他动态初始化,后续无序的变量初始化都是无序的.否则,对于每个其他动态初始化,变量的无序初始化是不确定地排序的.[ 注意:此定义允许与另一个序列同时初始化一系列有序变量.- 尾注 ]

"不确定顺序"是保证单线程执行的部分.根据定义,排序{before,after,indeterminately}的概念仅在单个线程中有意义:

[intro.execution]/13 之前的顺序是......由单个线程执行的评估之间的关系......