在C ++中销毁全局对象和atexit之间的顺序

时间:2013-04-15 07:43:40

标签: c++ atexit order-of-execution global-object

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

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

static MyClass g_class;

void onExit()
{
    // do some destruction
}

int main()
{
    atexit(onExit);

    return 0;
}

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

我想知道全局对象寄存器顺序和atexit寄存器顺序使用相同的顺序表。 或者全局对象顺序和atexit顺序之间没有关系?

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

1 个答案:

答案 0 :(得分:15)

UPDATE: OP造成了一些混乱,似乎VC11确实表现得像C ++ 11 Standard所规定的那样。以下答案是在假设没有的情况下编写的。

因此,这个问题的答案是:

  

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

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


  

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

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

  

使用静态存储的初始化对象(即生命周期(3.8)已开始的对象)的析构函数(12.4)   持续时间是从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在这方面是合规的,如live example所示。