Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C+中全局对象的销毁与atexit之间的顺序+;_C++_Atexit_Order Of Execution_Global Object - Fatal编程技术网

C++ C+中全局对象的销毁与atexit之间的顺序+;

C++ C+中全局对象的销毁与atexit之间的顺序+;,c++,atexit,order-of-execution,global-object,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; } 我发现在Visual Studio 2012和gcc4.7.2中,onExit()在MyClass::~MyClass()之前

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

我有一个全局对象和寄存器
atexit
函数,如下所示:

static MyClass g_class;

void onExit()
{
    // do some destruction
}

int main()
{
    atexit(onExit);

    return 0;
}
我发现在Visual Studio 2012和gcc4.7.2中,
onExit()
MyClass::~MyClass()
之前被调用。我确定在全局对象(比如
g_类
)销毁之前总是调用
onExit

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

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

更新:操作造成了一些混乱,而且似乎VC11确实按照C++11标准的规定运行。下面的答案是在假设没有的情况下写的

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

我确定在全局对象(比如
g_类
)销毁之前总是调用
onExit

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


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

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

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

此外,根据第3.6.3/3段:

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

因此,在您的情况下,
onexit()
应该在
MyClass
的析构函数之前调用


据我所知,Clang 3.2和GCC 4.8.0在这方面是兼容的,如图所示。

我怀疑订单不是100%确定的。你为什么在意?在
MyClass
之前创建另一个全局对象,并在其构造函数中调用
atexit(onExit)
进行检查。要控制对象的生存期,请使用动态对象。实际上,我有一个单例内存管理器对象被atexit破坏,全局对象使用由该内存管理器管理的成员变量。因此,全局对象在memorymanager被atexit销毁之前被销毁。@zelon:[主题外]作为一个无关的注释,在文件范围(全局范围)变量上使用
static
关键字可能不会像您认为的那样。也就是说,示例代码中的
静态
是多余的。g++是否兼容取决于编译器选项和平台。(如果可以,它是兼容的,但由于在许多平台上,
atexit
功能是由平台提供的,因此并不总是合理可行。)抱歉。我写错了。onexit()在~MyClass之前调用。我在整理示例代码时感到很困惑。@zelon:好的。然后行为是正确的,这就是C++标准所指定的。