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?
DLL_PROCESS_DETACH
– Skat