静态(全局)对象的初始化是如何发生的

How does initialization of static (global) objects happen

本文关键字:初始化 何发生 对象 全局 静态      更新时间:2023-10-16

我试图弄清楚全局对象的构造函数是如何调用的。 我知道在使用翻译单元中的任何内容之前都会调用它们,我对此很好。 我试图找出在Linux和Windows(x86和x64)中如何做到这一点。

似乎记得Windows(x86)使用链表进行构建和破坏,但是我很难找到有关此问题的任何资源。

我找到了以下有关相关主题的材料,但似乎没有什么能准确涵盖我正在寻找的内容。

  • http://blogs.msdn.com/b/freik/archive/2005/03/17/398200.aspx

  • http://msdn.microsoft.com/en-us/library/9b372w95.aspx

  • http://msdn.microsoft.com/en-us/library/7kcdt6fy.aspx

和 PE 文件格式文档。

谁能指出我找到这些信息的正确方向?

以防万一你不明白,我这里有代码来演示。来源A.cpp

#include "stdafx.h"
extern bool DoFunctionB();
class MyClassA {
protected:
    bool bIsInitialized;
    bool bIsBInitialized;
public:
    MyClassA () : bIsInitialized(true) {
        bIsBInitialized = DoFunctionB();
    }
    bool IsInitialized() {
        return bIsInitialized;
    }
};

static MyClassA MyClassGlobal;
bool DoFunctionA() {
    return MyClassGlobal.IsInitialized();
}

来源B.cpp

#include "stdafx.h"
extern bool DoFunctionA();
class MyClassB {
protected:
    bool bIsInitialized;
    bool bIsAInitialized;
public:
    MyClassB () : bIsInitialized(true) {
        bIsAInitialized = DoFunctionA();
    }
    bool IsInitialized() {
        return bIsInitialized;
    }
};

static MyClassB MyClassGlobal;
bool DoFunctionB() {
    return MyClassGlobal.IsInitialized();
}

主.cpp

#include "stdafx.h"
extern bool DoFunctionA();
extern bool DoFunctionB();
int _tmain(int argc, _TCHAR* argv[])
{
    bool a = DoFunctionA();
    bool b = DoFunctionB();
    return 0;
}

将这些内容添加到新的 Windows 控制台应用。 将断点放在构造函数和 DoFunctionX() 代码中。 按 F11 并逐步完成它。 您将看到,无论哪个全局初始值设定项首先被调用,都将在初始化该文件中的静态对象之前使用另一个 cpp 文件中的 DoFunction。

不管你认为标准是什么。 这就是编译器所做的。 这是你必须关注的危险。

如果您在构造函数中将堆栈提升 2 个步骤,您将看到我已经告诉您的指针列表。

快乐编码。

认为在使用对象之前必须运行全局构造函数是错误的。 我已经基于这个假设修复了许多错误,但它根本不是真的。 不适用于 gcc,也不适用于 MSVC,当然不适用于 XCode。

您可以在 gcc 中指定一个属性((init_priority(X))) 来强制排序,

或 #pragma init_seg({ 编译器 | 库 | 用户 |"section-name" [, func-name]} ) for msvc.

使用 XCode 时,初始化代码将按照对象文件传递到链接器的顺序运行。

我不认为有标准,如果有的话,很少有人遵循它。 由工具创建者决定如何跟踪初始化的内容和时间。