Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does initialization of static (global) objects happen

I am trying to figure out exactly how constructors for global objects are called. I understand that they are called before anything in a translation unit is used, and I am fine with that. I am trying to find out how in Linux and Windows (x86 and x64) this is accomplished.

I seem to remember that Windows (x86) used a linked list for construction and destruction, but I am having trouble finding any resources on this matter.

I have found the following material on related topics, but nothing seems to cover exactly what I am looking for.

  • 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

And the PE file format document.

Could anyone point me in the correct direction to find this information?

like image 453
Graznarak Avatar asked Nov 10 '22 12:11

Graznarak


1 Answers

Just in case your failing to understand I have code here to demonstrate. 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;
}

Add these to a new windows console app. Place breakpoints in the constructors, and in the DoFunctionX() code. Hit F11 and step through it. You will see that whichever global initializer gets called first will use the DoFunction in the other cpp file before the static object in that file gets initialized.

Regardless of what you think the standard may be. This is what compilers do. And its a hazard that you have to be concerned with.

And if you step up the stack 2 steps when your in the constructor you will see the list of pointers that I've already told you about.

Happy Coding.

like image 164
Dan Avatar answered Nov 15 '22 06:11

Dan