24

atexit我想知道在销毁全局对象和在 C++中可以确定顺序

我有一个全局对象和注册atexit函数,如下所示:

static MyClass g_class;

void onExit()
{
    // do some destruction
}

int main()
{
    atexit(onExit);

    return 0;
}

我发现onExit()之前MyClass::~MyClass()在 Visual Studio 2012 和 gcc4.7.2 中调用过。我确定onExit总是在全局对象(如g_class)销毁之前调用它吗?

我想知道全局对象注册顺序和atexit注册顺序使用相同的顺序表。还是全局对象顺序和顺序之间没有关系atexit

编辑:对不起,我写错了。我在整理示例代码时很困惑。onExit()在 ~MyClass() 之前调用。

4

1 回答 1

20

更新: OP 造成了一些混乱,看起来 VC11 确实按照 C++11 标准的规定行事。以下答案是在假设没有的情况下编写的。

因此,这个问题的答案:

我确定onExit总是在全局对象(如g_class)销毁之前调用它吗?

"Yes",只要您使用的是完全兼容的编译器。


我发现之前在 Visual Studio 2012MyClass::~MyClass()中调用过。onExit()

如果是这种情况,那么它是 VC11 中的一个错误。根据 C++11 标准的第 3.6.3/1 段:

具有静态存储持续时间的已初始化对象(即其生命周期 (3.8) 已开始的对象)的析构函数 (12.4) 作为从 (18.5) 返回main的结果和调用std::exit(18.5) 的结果而被调用。[...]

此外,根据第 3.6.3/3 段:

如果具有静态存储持续时间的对象的初始化完成在调用之前排序std::atexit(参见<cstdlib>18.5),则对传递给的函数std::atexit的调用在调用对象的析构函数之前排序。

因此,在您的情况下,onexit()应该在MyClass.

据我所知,Clang 3.2 和 GCC 4.8.0 在这方面是合规的,如现场示例所示。

于 2013-04-15T07:49:52.170 回答