全局变量和静态内联数据成员相对于彼此的初始化顺序是否得到保证?

Kex*_*iii 6 c++ static-members initialization-order language-lawyer c++17

下面的代码在同一个翻译单元中,并且A::v在之后定义的x,为什么A::v没有初始化为“ok”?

#include <string>
#include <iostream>

std::string foo() {
    return "OK";
}

std::string x = foo();


struct A {
    static inline std::string v = x;
};

int main() {
    std::cout << A::v << std::endl; // didn't print "OK", why?
}

Run Code Online (Sandbox Code Playgroud)

Bri*_*ian 8

根据[basic.start.dynamic]/1,具有静态存储持续时间的非内联非模板化非块变量具有“有序”初始化,而具有静态存储持续时间的内联非模板化非块变量具有“部分有序” “初始化。

根据[basic.start.dynamic]/3,在以下情况下,我们仅在两个具有静态存储持续时间的非块变量之间有初始化顺序保证:

  • 第一个和第二个变量都进行了有序初始化,并且第一个变量的定义先于第二个变量的定义,或者
  • 第一个变量具有部分有序初始化,第二个变量具有有序初始化,并且第二个变量的定义位于第一个变量的定义之前,或者
  • 两个变量都具有部分有序的初始化,并且第二个变量的每个定义前面都有第一个变量的定义。

因此,如果非内联变量在内联变量之前定义,我们就没有初始化顺序保证。当内联变量是第一个时,我们只有初始化顺序保证。所以在这段代码中,v可以在之前初始化x,导致未定义的行为。