ARM C++ABI:构造函数/析构函数返回值
ARM C++ ABI: Constructor/destructor return values
我一直在阅读Clang源代码,发现了一些关于ARM C++ABI的有趣之处,但我似乎无法理解其理由。来自ARM ABI文档的在线版本:
此ABI要求C1和C2构造函数返回This(而不是void函数(,以便C3构造函数可以尾部调用C1构造函数,并且C1构造函数可以尾部调用C2。
(类似于非虚拟析构函数(
我不确定C1
、C2
和C3
在这里引用了什么。。。本节是对通用(即安腾(ABI§3.1.5的修改,但该节(至少在本在线版本中(只是简单地说明:
构造函数返回void结果。
无论如何,我真的不明白这是什么目的:让构造函数返回this如何允许尾部调用优化,在什么情况下?
据我所知,构造函数唯一可以尾调用另一个具有相同this
返回值的构造函数的情况是,派生类只有一个基类,一个平凡的构造函数体,没有具有非平凡构造函数的成员,也没有虚拟表指针。事实上,使用返回void
的尾部调用进行优化似乎更容易,而不是更困难,因为这样就可以消除单个基类的限制(在多基类的情况下,从上次调用的构造函数返回的this
指针将不是派生对象的this
指针(。
我在这里错过了什么?ARM调用约定是否使this
返回成为必要?
好的,来自@Michael的有用链接让这一切变得清晰。。。C1
、C2
和C3
分别指安腾ABI:对"完整对象构造函数"、"基本对象构造函数"answers"完整对象分配构造函数"的名称篡改
<ctor-dtor-name> ::= C1 # complete object constructor
::= C2 # base object constructor
::= C3 # complete object allocating constructor
::= D0 # deleting destructor
::= D1 # complete object destructor
::= D2 # base object destructor
C3
/"完整对象分配构造函数"是构造函数的一个版本,它不是在通过this
参数传递给它的已经分配的存储上操作,而是在内部(通过operator new
(分配内存,然后调用C1
/"完全对象构造函数",这是用于完整对象情况的普通构造函数。由于C3
构造函数必须返回指向新分配和构造的对象的this
指针,因此C1
构造函数也必须返回this
指针才能使用尾部调用。
C2
/"基对象构造函数"是派生类在构造基类子对象时调用的构造函数;CCD_ 21和CCD_。在virtual
继承的情况下,C1
构造函数可以通过对virtual
基类构造函数的调用和对C2
构造函数的尾调用来实现,因此如果前者返回this
,则后者也应该返回CCD_ 28。
析构函数的情况略有不同,但有关联。根据ARM ABI:
类似地,我们要求D2和D1返回this,这样D0就不需要保存和恢复this,并且D1可以尾调用D2(如果没有虚拟基(。D0仍然是一个空函数。
D0
/"删除析构函数"是在删除对象时使用的,它调用D1
/"完整对象析构函数",然后用this
指针调用operator delete
以释放内存。使D1
析构函数返回this
允许D0
析构函数使用其返回值来调用operator delete
,而不必将其保存到另一个寄存器或溢出到内存;类似地,D2
/"基本对象析构函数"也应该返回this
。
ARM ABI还增加了:
我们不需要到虚拟析构函数的thunk来返回this。这样的撞击必须调整析构函数结果,防止它尾部调用析构函数,并取消任何可能的保存。
因此,只有D1和D2析构函数的非虚拟调用才能返回this。
如果我理解正确,这意味着只有当D0
静态调用D1
时(即在非virtual
析构函数的情况下(,才能使用此保存-还原省略优化。
- 为什么在使用转换构造函数赋值后调用C++类的析构函数?
- 复制构造函数 C++ 在析构函数上返回奇怪的字母
- C++类析构函数使用新值而不是实际值
- 为什么添加析构函数(甚至是空的)会破坏我的结构,该结构使用 ref 转发和折叠来保存 ref 或值的副本?
- 如何从类成员函数返回指针,例如 size_t * class :: function(); 并使用类析构函数 ~size
- 是否可以使用类的析构函数内部函数来重置值?
- 迭代器和简单的赋值/析构函数
- 函数返回的类上的析构函数
- Boost 无锁队列断言用于简单的赋值和析构函数
- 在共享指针的值中调用 std::swap 调用一堆构造函数和析构函数
- GCC 9.1 返回 void& 作为显式析构函数调用的结果类型。这是一个错误吗?
- 返回堆栈变量时停止调用析构函数
- Clang修改析构函数中的返回值
- std::current_exception 是否应该从类析构函数中的 catch 块返回非空值
- 从函数调用析构函数返回的对象
- std:map 析构函数是否调用键析构函数以及值析构函数?
- 返回值优化和析构函数调用
- 返回值时调用析构函数
- ARM C++ABI:构造函数/析构函数返回值
- 为什么在返回临时(右值)时,析构函数在移动构造函数之前被调用