Screenplay: C++: Global Objects Initialization

Global Variables

#include <string>
#include <iostream>


std::string global_str("global_str");

int main()
{
    std::cout << global_str << std::endl;
    return 0;
}

Discussion

  • obviously somebody must call constructor and destructor

  • discuss ELF and sections?

Define class with output …

#include <iostream>
#include <string>


#ifndef __HAVE_THING_H__
#define __HAVE_THING_H__

class Thing
{
public:
    Thing(const std::string& content) : _content(content)
    {
        std::cout << "ctor: " << _content << std::endl;
    }
    ~Thing()
    {
        std::cout << "dtor: " << _content << std::endl;
    }

    const std::string& content() const { return _content; }

private:
    std::string _content;
};

#endif

Constructor and Destructor Order in Same File

#include "thing.h"

#include <iostream>


static Thing thing1("thing1");
static Thing thing2("thing2");

int main()
{
    return 0;
}

Discussion

  • thing1 and thing2 constructed in definition order

  • thing1 and thing2 denstructed in reverse definition order

  • This can be counted on!

Constructor and Destructor Order Across Files

int main()
{
    return 0;
}
#include "thing.h"

Thing thing1("thing1");
#include "thing.h"

Thing thing2("thing2");

From this build two different executables (see CMakeLists.txt)

$ ./20-different-files
ctor: thing1
ctor: thing2
dtor: thing2
dtor: thing1
$ ./20-different-files-reversed
ctor: thing2
ctor: thing1
dtor: thing1
dtor: thing2

Discussion

  • Standard says, initialization (and destruction) order is unspecified across compilation units

  • Here, Linux, gcc, ld: link order

  • Static libraries: different story

  • Shared libraries: different story

Constructor and Destructor Order Across Files: Dependencies, Bugs

int main()
{
    return 0;
}
#include "thing.h"

Thing thing1("thing1");

Here is the dependency: thing2’s content is thing1’s plus extra stuff,

#include "thing.h"

extern Thing thing1;

Thing thing2(thing1.content() + " BUG!!");

From this build two different executables (see CMakeLists.txt)

$ ./30-different-files-bug
ctor: thing1
ctor: thing1 BUG!!
dtor: thing1 BUG!!
dtor: thing1
$ ./30-different-files-bug-reversed
ctor:  BUG!!
ctor: thing1
dtor: thing1
dtor:  BUG!!

Discussion