我有一个主程序 (main.cpp
) 和一个共享库(test.h
和 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;
}
这是我在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的错误还是我漏看了什么?