c++ - 共享库中静态对象的销毁顺序

标签 c++ windows singleton shared-libraries object-destruction

我有一个主程序(main.cpp)和一个共享库(test.htest.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/

相关文章:

java - 为什么静态单例是避免 'DCL' 的简单而优雅的解决方案?

由于私有(private)保护级别,Swift 初始值设定项无法访问

c++ - 弹跳物体的三角函数

c++ - 通过 NULL 指针访问类成员

c++ - 列出目录 C++ 中的文件

windows - 如何确定 Windows 计算机的身份?

c# - 以编程方式为桌面 "shortcut"创建快捷键组合

c++ - c++中不规则的文件写入性能

windows - 使 HTML 不适用于 Windows 10 中的 Sphinx 文档

android - Proguard 使用 kotlin-reflect 为所有 INSTANCE 字段生成注释