iva*_*nys 5 c++ destructor atexit
这种情况下订单是保证的还是UB的?
#include <iostream>
#include <cassert>
using namespace std;
struct TraceHelper
{
TraceHelper()
{
cout << "TraceHelper::constructor()" << endl;
}
~TraceHelper()
{
cout << "TraceHelper::destructor()" << endl;
}
};
void trace_fn()
{
static TraceHelper th;
cout << "trace_fn()" << endl;
}
void my_atexit()
{
cout << "my_atexit()" << endl;
}
int main()
{
cout << "Entered main()" << endl;
assert(0 == atexit(my_atexit));
trace_fn();
trace_fn();
cout << "Exiting main()" << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
#include <iostream>
#include <cassert>
using namespace std;
struct TraceHelper
{
TraceHelper()
{
cout << "TraceHelper::constructor()" << endl;
}
~TraceHelper()
{
cout << "TraceHelper::destructor()" << endl;
}
};
void trace_fn()
{
static TraceHelper th;
cout << "trace_fn()" << endl;
}
void my_atexit()
{
cout << "my_atexit()" << endl;
}
int main()
{
cout << "Entered main()" << endl;
assert(0 == atexit(my_atexit));
trace_fn();
trace_fn();
cout << "Exiting main()" << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我们在这里看到的是 main 函数和std::exit之间的交互:
\n\n\n从主函数返回,[...] 执行正常的函数终止(调用具有自动存储持续时间的变量的析构函数),然后执行 std::exit,传递 return 语句的参数(或 xe2 \x80\x8b0\xe2\x80\x8b(如果使用隐式返回)as\nexit_code。
\n
就静态对象的销毁而言,与问题相关的是以下几行:
\n\n\n如果静态对象 A 的初始化完成是在调用某个函数 F 的 std::atexit 之前排序的,则终止期间对 F 的调用是在 A 的析构开始之前排序的。
\n如果对某些函数 F 的 std::atexit 的调用被排序在静态对象 A 的初始化完成之前,则 A 的销毁开始被排序在终止期间对 F 的调用之前。
\n
在问题的代码中,在函数中创建静态对象之前my_atexit()使用注册了该函数。因此,析构函数的调用发生在调用 之前。该行为符合预期。std::atexit()thtrace_fn()TraceHelpermy_atexit()