初始化顺序

Che*_*han 2 c++ initialization

我的问题与全局对象的初始化顺序有关。这里有一定程度的讨论:C++: When (and how) are C++ Global Static Constructors Called?

我想知道的是,如何保证某些系统库对象(尽管无法想到示例)在应用程序中使用之前已初始化?(我知道解决方案是将这样的对象包装在一个函数中,但我想了解它在今天的编译器中是如何处理的)

John Levine 的《链接器和加载器》一书中也讨论了这一点,同时讨论了 .init 和 .finit 部分,但目前的技术状况尚不清楚。

Win*_*ert 5

一个例子是cout

编译器并不能真正保证这些对象在使用之前就已构建。采取这个代码:

struct Foo
{

    Foo();
}foo;

#include <iostream>

Foo::Foo()
{
    std::cout << "Hello World";
}

int main() {}
Run Code Online (Sandbox Code Playgroud)

它会出现段错误,因为 foo 对象是在 cout 之前构建的。当它尝试使用 cout 时,就会发生不好的事情。

基本上,所有全局对象都将插入代码来构造它们,并在 main 之前运行。一旦你进入 main,你就安全了,所有的对象都被构建好了。在此之前,这取决于它们的定义顺序。这就是为什么我可以在声明 foo 全局后通过包含 iostream 来破坏它。

  • @Chethan:这确实很重要。编译器有一些技巧来处理初始化和 iostream 的问题。一种常见的模式是使用私有类型来计算创建的类型实例的数量,并在私有命名空间内的“iostream”中定义该类型的命名空间级别变量。当这些对象的构造函数作为 TU 静态初始化的一部分运行时,它会检查它是否是第一个对象,在这种情况下它会初始化 iostream。因为这些对象位于包含“iostream”的所有翻译单元中,所以保证了执行顺序 (2认同)