.dtors
中的函数与使用atexit()
调用的函数有什么区别?
据我了解,标有((destructor))
属性的函数位于.dtors
段,并在退出后调用。同样,使用atexit(fctName)
添加的函数放在一个数组中,并在正常执行结束后调用。
那么为什么C ++在这里提供了两种截然不同的机制呢?是否只有一个可以做的明显的事情?我只能使用atexit()
动态添加函数吗?
首先调用哪些函数,.dtors
中的函数或使用atexit()
添加的函数?
答案 0 :(得分:1)
来自linux man-pages atexit()在正常进程终止时被调用,可以通过exit(3)或通过程序的main()返回。
对于.ctors / .dtors,在加载/卸载定义它们的共享库时调用它们。
这些发生的顺序非常明显。
答案 1 :(得分:0)
C ++没有.dtors
。一些实现可能。它是跟踪全局对象的析构函数的合理机制。据我了解,它是一个编译时列表。
atexit
个处理程序。这意味着只有在运行时必要时才能添加函数。
有关问题的最后部分(以及更多详情),请参阅When is a function registered with atexit() called
答案 2 :(得分:-1)
静态对象析构函数的一个合法实现是注册
它们在构造函数完成时使用atexit
。标准
要求订单与使用此实现时相同。
主要区别在于静态对象的析构函数是
析构函数:如果对象是自动调用它们
完全构造,无需您注册
他们。他们有一个this
参数来访问该对象。
编辑:
使其完全清楚:给定
T obj; // where obj has static lifetime...
编译器会生成一个函数:
void __destructObj()
{
obj.~T();
}
以及以下初始化代码:
new (&obj) T;
std::atexit( __destructObj );
这不管obj
的范围如何;相同的基本代码适用于
局部静态和命名空间范围内的对象。 (如果是
在本地对象中,编译器还必须生成标志和代码
测试它以表明对象是否已经初始化;
它还必须采取措施确保线程安全。)
事实上,很难看出编译器如何能够做到这一点
(虽然它可能会生成代码内联以执行std::atexit
所做的事情),
鉴于订购要求。