Static initialization and destruction of a static library's globals not happening with g++

moala picture moala · Nov 26, 2009 · Viewed 9.4k times · Source

Until some time ago, I thought a .a static library was just a collection of .o object files, just archiving them and not making them handled differently. But linking with a .o object and linking with a .a static library containing this .o object are apparently not the same. And I don't understand why...

Let's consider the following source code files:

// main.cpp
#include <iostream>
int main(int argc, char* argv[]) {
    std::cout << "main" << std::endl;
}

// object.hpp
#include <iostream>
struct Object
{
    Object() { std::cout << "Object constructor called" << std::endl; }
    ~Object() { std::cout << "Object destructor called" << std::endl; }
};

// object.cpp
#include "object.hpp"
static Object gObject;

Let's compile and link and run this code:

g++ -Wall object.cpp main.cpp -o main1
./main1
> Object constructor called
> main
> Object destructor called

The constructor an the destructor of the global gObject object is called.

Now let's create a static library from our code and use (link) it in another program:

g++ -Wall -c object.cpp main.cpp
ar rcs lib.a object.o
g++ -Wall -o main2 main.o lib.a
./main2
> main
  • gObject's constructor and destructor are not called... why?
  • How to have them automatically called?

Thanks.

Answer

Arkaitz Jimenez picture Arkaitz Jimenez · Nov 26, 2009

.a static libraries contain several .o but they are not linked in unless you reference them from the main app.
.o files standalone link always.

So .o files in the linker always go inside, referenced or not, but from .a files only referenced .o object files are linked.

As a note, static global objects are not required to be initialized till you actually reference anything in the compilation unit, most compilers will initialize all of them before main, but the only requirement is that they get initialized before any function of the compilation unit gets executed.