Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Destruction order of static objects in shared libraries

I have a main program (main.cpp) and a shared library (test.h and test.cpp):

test.h:

#include <stdio.h>

struct A {
    A() { printf("A ctor\n"); }
    ~A() { printf("A dtor\n"); }
};

A& getA();

test.cpp:

#include "test.h"

A& getA() {
    static A a;
    return a;
}

main.cpp:

#include "test.h"

struct B {
    B() { printf("B ctor\n"); }
    ~B() { printf("B dtor\n"); }
};

B& getB() {
    static B b;
    return b;
}

int main() {
    B& b = getB();
    A& a = getA();
    return 0;
}

This is how I compile these sources on Linux:

g++ -shared -fPIC test.cpp -o libtest.so
g++ main.cpp -ltest

Output on Linux:

B ctor
A ctor
A dtor
B dtor

When I run this example on Windows (after some adjustments like adding dllexport) I get with MSVS 2015/2017:

B ctor
A ctor
B dtor
A dtor

To me the first output seems to be compliant with the standard. For example see: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf

From paragraph 3.6.3.1:

If the completion of the constructor or dynamic initialization of an object with static storage duration is sequenced before that of another, the completion of the destructor of the second is sequenced before the initiation of the destructor of the first.

That is if B object is constructed first it should be destroyed last - that what we see on Linux. But the Windows output is different. Is it a MSVC bug or am I missing something?

like image 709
eXXXXXXXXXXX2 Avatar asked Feb 06 '19 21:02

eXXXXXXXXXXX2


1 Answers

The whole concept of a DLL is outside the scope of the C++ standard.

With Windows, DLLs can be unloaded dynamically during program execution. To help support this, each DLL will handle the destruction of static variables constructed while it was loaded. The result is that the static variables will be destroyed in an order that depends on the unload order of the DLLs (when they receive the DLL_PROCESS_DETACH notification). DLLs and Visual C++ run-time library behavior describes this process.

like image 65
1201ProgramAlarm Avatar answered Sep 20 '22 04:09

1201ProgramAlarm