我有一个主程序(main.cpp
)和一个共享库(test.h
和test.cpp
):
测试.h:
#include <stdio.h>
struct A {
A() { printf("A ctor\n"); }
~A() { printf("A dtor\n"); }
};
A& getA();
测试.cpp:
#include "test.h"
A& getA() {
static A a;
return a;
}
主.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;
}
这就是我在 Linux 上编译这些源代码的方式:
g++ -shared -fPIC test.cpp -o libtest.so
g++ main.cpp -ltest
Linux 上的输出:
B ctor
A ctor
A dtor
B dtor
当我在 Windows 上运行此示例时(经过一些调整,例如添加dllexport
),我得到了 MSVS 2015/2017:
B ctor
A ctor
B dtor
A dtor
对我来说,第一个输出似乎符合标准。例如参见: http ://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf
从第 3.6.3.1 段开始:
如果具有静态存储持续时间的对象的构造函数或动态初始化的完成顺序在另一个之前,则第二个的析构函数的完成顺序在第一个的析构函数的启动之前。
也就是说,如果B
对象首先被构造,它应该最后被销毁——这就是我们在 Linux 上看到的。但是 Windows 输出不同。是 MSVC 错误还是我遗漏了什么?