Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In what order are global constructors called

In what order get the constructors of global object in C++ called?

This question arises in the context of a memory pool that manages the memory needs for some consumers. I was presented with a rather large source code which defines at global namespace some consumers just using heap functions. A memory pool should be added without changing the namespace of the consumers. So, I added a pool class and a definition at global namespace and modified each consumer class to get memory from the instance of the class "thePool". Unfortunately at the end of the execution when it comes to call all global destructors I get a nice segfault. gdb backtrace shows that the branch to pool::free produces the segfault. This sounds odd to me. However, I boiled it down to a very simple pool/consumer example which lives on the global namespace. Unfortunately this does not reproduce the segfault -- the destructor of pool gets called after all destructors of the consumer. Is this pure luck, or a well-educated guess of g++ 4.5 ?

Here the boiled down example:

#include<iostream>

using namespace std;


struct pool {
  pool() {
    cout << "pool::pool" << endl;
  }
  ~pool() {
    cout << "pool::~pool" << endl;
  }
  void get() {
    cout << "pool::get" << endl;
  }
  void free() {
    cout << "pool::free" << endl;
  }
};

pool thePool;


struct consumer {
  ~consumer() {
    cout << "consumer::~consumer" << endl;
    thePool.free();
  }
  consumer() {
    cout << "consumer::consumer" << endl;
    thePool.get();
  }
};



consumer a,b;

int main() {
}

The output is:

pool::pool
consumer::consumer
pool::get
consumer::consumer
pool::get
consumer::~consumer
pool::free
consumer::~consumer
pool::free
pool::~pool

Nice! Just as I wanted it. Pure luck? I mean the dtor of pool could have been called before destroying consumer a or b, right?

The question to answer is: "In what order are the cons of global objects called?"

like image 448
ritter Avatar asked Aug 28 '11 17:08

ritter


1 Answers

Global variables are initialized in the order in which they're declared. So their constructor will be called in the same order in which they're initialized. This is true within one translation unit. However, the initialization order across multiple translation-units is not defined by the language specification.

And their destructors are called in the reverse order of their initialization as usual.

like image 155
Nawaz Avatar answered Oct 03 '22 17:10

Nawaz