0

.dtors函数 in和调用 using的函数有什么区别atexit()

据我了解,标有((destructor))属性的函数位于.dtors段中,并在退出后调用。同样,使用添加的函数atexit(fctName)被放置在一个数组中,并在正常执行结束后调用。

那么为什么 C++ 在这里提供了两种截然不同的机制呢?有什么不同的事情只能用一个来完成吗?我只能使用动态添加一个函数atexit()吗?

还有哪些首先被调用,函数中.dtors或使用添加的函数atexit()

4

3 回答 3

1

linux 手册页atexit() 在正常进程终止时被调用,或者通过 exit(3) 或通过从程序的 main() 返回。

至于 .ctors / .dtors,它们在定义它们的共享库被加载/卸载时被调用。

这些发生的顺序非常明显。

于 2015-02-02T15:12:16.823 回答
0

C++ 没有.dtors. 一些实现可能。跟踪全局对象的析构函数是一种合理的机制。据我了解,这是一个编译时列表。

atexit不过,处理程序是在运行时添加的。这意味着只有在运行时需要它们时才可以添加函数。

对于您问题的最后一部分(以及更多详细信息),请参阅何时使用 atexit() 注册的函数调用

于 2015-02-02T15:06:29.560 回答
-1

静态对象的析构函数的一种合法实现是atexit在构造函数完成时注册它们。该标准要求顺序与使用此实现时的顺序相同。主要区别在于静态对象 析构函数是析构函数:如果对象完全构造,它们将被自动调用,而您无需注册它们。他们有一个this参数来访问该对象。

编辑:

说得很清楚:给定

T obj;      //  where obj has static lifetime...

编译器会生成一个函数:

void __destructObj()
{
    obj.~T();
}

以及以下初始化代码:

new (&obj) T;
std::atexit( __destructObj );

这不管范围obj;相同的基本代码适用于命名空间范围内的局部静态和对象。(在本地对象的情况下,编译器还必须生成一个标志和代码来测试它以指示对象是否已经初始化;它还必须采取措施确保线程安全。)

std::atexit事实上,考虑到排序要求,很难看出编译器如何以其他方式执行此操作(尽管它可能会生成内联代码来执行此操作)。

于 2015-02-02T15:07:38.307 回答