如何使共享库的全局对象在 exit() 函数中存活?

问题描述 投票:0回答:1

我遇到共享库的全局对象在使用之前被销毁的问题。我不知道所有细节,也无法控制使用该库的应用程序,但我对正在发生的事情的假设是:

  • 应用程序的 main() 函数返回
  • exit() 函数被调用
  • exit() 销毁全局对象
  • exit() 调用atexit-functions,即使用atexit() 函数注册的函数
  • atexit-functions 调用库的函数,该函数使用已经被销毁的全局对象

我需要这个物体才能幸存下来。 动态创建能解决问题吗?其中任何一个:

Object *pObj = new Object;
Object &rObj = *(new Object);

据我了解,动态创建的对象会生存下来。但是指向对象的变量又如何呢? pObj 和 rObj 本身就是全局变量。它们不会像具有静态存储持续时间的对象被销毁一样在 atexit 函数之前被销毁吗?

c++ global-variables exit
1个回答
0
投票
  • exit() 销毁全局对象
  • exit() 调用atexit-functions,即使用atexit() 函数注册的函数

不完全是。全局对象的销毁和对 atexit 函数的调用可以交错进行。该顺序取决于全局对象的构造顺序以及对

atexit
的调用。

[basic.start.term/5]

如果用static完成对象的初始化 存储持续时间强烈发生在调用

std​::​atexit
之前 (参见support.start.term), 对传递给
std​::​atexit
的函数的调用在 调用该对象的析构函数。如果致电
std​::​atexit
强烈发生在初始化完成之前 具有静态存储持续时间的对象,对析构函数的调用 在调用传递给的函数之前对对象进行排序
std​::​atexit

如果您的应用程序是单一的(没有动态加载代码)并且您不从全局对象的构造函数中调用

std::atexit
,那么您应该没问题,至少对于在
main
之前调用全局构造函数的常见实现是这样。严格来说,这是不可移植的,除非您仔细安排每个全局的动态初始化发生在对
std::atexit
的相应调用之前。请参阅此处了解完整的法律术语)。

为了绝对确定,您可以使用nifty counter惯用语。

© www.soinside.com 2019 - 2024. All rights reserved.