2

我知道 C++ 中的静态初始化顺序存在很大问题,基本上没有跨翻译单元的保证,但是在同一个翻译单元中应该保证静态对象被初始化以便它们出现。那么为什么会这样呢?

#include <iostream>

struct Foo {};

class SequentialTypeIDDispenser
{
private:
    static inline int count = 0;
public:
    static int init() { std::cout << "initialising static member\n"; return count++; }
    template <typename type>
    static inline int ID = init();

};
 

class Horse
{public:
    static char init()
    {
        // Doesn't work, prints 0 all three times
        std::cout << SequentialTypeIDDispenser::template ID<char> << "\n";
        std::cout << SequentialTypeIDDispenser::template ID<double> << "\n";
        std::cout << SequentialTypeIDDispenser::template ID<float> << "\n";

        return 0;
    }
    static inline char member = init();
// Why is this being initialised before the static 
// members of the above class?
};

int main()
{


    // Now it works
    std::cout << SequentialTypeIDDispenser::template ID<char> << "\n";
    std::cout << SequentialTypeIDDispenser::template ID<double> << "\n";
    std::cout << SequentialTypeIDDispenser::template ID<float> << "\n";
    
    Horse horse;
    
}

打印输出为:

0
0
0
initialising static member
initialising static member
initialising static member
0
1
2

因此,我们遇到了一个静态类成员在其上方的静态类成员之前被初始化的情况。为什么会这样?

另外,还有一个我不明白的问题,为什么如果程序还没有开始初始化 ID,为什么它打印 0?这和未定义的意外一样吗?

4

1 回答 1

0

您的变量是动态初始化的,具有无序初始化:

无序动态初始化,仅适用于(静态/线程本地)类模板静态数据成员......未明确专门化。这种静态变量的初始化相对于所有其他动态初始化的顺序是不确定的......

[强调我的]

对于您的情况,初始化顺序是不确定的。

此外,动态分配可能会被推迟

动态初始化是否发生在main函数的第一条语句之前由实现定义

因此,正确的初始化可能发生函数的第一条语句之后main,或者至少在其中一个变量 a 被ODR used之前发生。

于 2021-09-01T13:39:40.733 回答