我有一个主程序(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 段开始:
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.
也就是说,如果 B
对象首先被构造,它应该最后被销毁——这就是我们在 Linux 上看到的。但是 Windows 输出不同。是 MSVC 错误还是我遗漏了什么?
最佳答案
DLL 的整个概念超出了 C++ 标准的范围。
在 Windows 中,DLL 可以在程序执行期间动态卸载。为了帮助支持这一点,每个 DLL 将处理在加载时构造的静态变量的销毁。结果是静态变量的销毁顺序取决于 DLL 的卸载顺序(当它们收到 DLL_PROCESS_DETACH 通知时)。 DLLs and Visual C++ run-time library behavior描述了这个过程。
关于c++ - 共享库中静态对象的销毁顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54562874/