Destruction order of static objects in shared libraries

  • A+
Category:Languages

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?

 


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.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: