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

时间:2014-02-21 08:09:16

标签: c++ c++11 global-variables

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

我似乎记得Windows(x86)使用链表进行构建和销毁,但我无法在此问题上找到任何资源。

我在相关主题上找到了以下材料,但似乎没有任何内容可以涵盖我正在寻找的内容。

和PE文件格式文件。

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

2 个答案:

答案 0 :(得分:1)

万一你不明白我在这里有代码来证明。 SourceA.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();
}

SourceB.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();
}

Main.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。

无论您认为该标准是什么。这就是编译器所做的。这是你必须关心的危险。

如果你在构造函数中升级了两个步骤,你会看到我已经告诉你的指针列表。

快乐编码。

答案 1 :(得分:0)

认为在使用对象之前必须运行全局构造函数是错误的。我已根据这个假设修正了很多错误,但事实并非如此。不适用于gcc,也不适用于MSVC,abd肯定不适用于XCode。

您可以在gcc中指定属性((init_priority(X)))来强制订单,

mspc的

或#pragma init_seg({compiler | lib | user |“section-name”[,func-name]})。

使用XCode时,初始化代码按目标文件传递给链接器的顺序运行。

我认为没有标准,如果有的话,很少有人关注它。由工具创建者决定他们如何跟踪最初的初始化和何时。