C++ 字符串常量和静态初始化顺序惨败

c++ string constant and static initialization order fiasco

本文关键字:顺序 初始化 静态 字符串 常量 C++      更新时间:2023-10-16

我试图了解静态初始化顺序惨败何时是一个真正的问题。如果我使用如下所示kName字符串常量,它会遭受静态初始化顺序惨败的任何问题吗?在这种情况下这是一个问题,因为可以在初始化kName之前创建Derived的实例,如main.cpp

// Base.cpp
namespace test {
class Base {
public:
  virtual ~Base() = default;
protected:
  explicit Base(const std::string &name);
};
} // namespace test
// Derived.cpp
namespace test {
static const std::string kName = "my name";
class Derived : public Base {
public:
  Derived() : Base(kName) {}
  ~Derived() override = default;
};
} // namespace test
// main.cpp
int main() {
  test::Derived instance{};
  return 0;
}

在所有"全局"变量初始化之前,不会调用 main 函数。这包括static成员变量以及namespace范围内的变量(static与否(。

所以在这种情况下,这没有问题,因为您在main函数中定义了instance

如果instance的定义是在main函数之外静态完成的,那就不一样了。

在特定翻译单元中,静态对象的初始化顺序保证是对象定义在该翻译单元中出现的顺序。销毁顺序保证与初始化顺序相反。但是,不能保证跨翻译单元初始化静态对象的顺序。这就是所谓的静态初始化订单惨败。

所以在这里你不会有静态初始化顺序惨败。