C1好的,来自@Michael 的有用链接使这一切都变得清晰C2...... C3ABI:
<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基类构造函数”是派生类在构造基类子对象时调用的构造函数;C1和C2构造函数的语义在virtual继承的情况下是不同的,并且为了优化目的也可以以不同的方式实现。在virtual继承的情况下,C1构造函数可以通过调用virtual基类构造函数然后尾调用C2构造函数来实现,因此如果前者调用,后者也应该返回this。
析构函数的情况略有不同但相关。根据 ARM ABI:
类似地,我们要求 D2 和 D1 返回这个,这样 D0 就不需要保存和恢复这个,并且 D1 可以尾调用 D2(如果没有虚拟碱基)。D0 仍然是一个 void 函数。
/ “ D0deleting destructor”在删除对象时使用,它调用D1/“complete object destructor”,然后operator delete用this指针调用以释放内存。让D1析构函数返回this允许D0析构函数使用其返回值来调用operator delete,而不必将其保存到另一个寄存器或将其溢出到内存中;同样,D2/"base object destructor" 也应该返回this。
ARM ABI 还添加了:
我们不需要对虚拟析构函数的 thunk 来返回this。这样的重击必须调整析构函数的结果,防止它尾调用析构函数,并取消任何可能的保存。
因此,只能依靠 D1 和 D2 析构函数的非虚拟调用来返回this。
如果我理解正确,这意味着这种保存-恢复-省略优化只能在静态D0调用时使用D1(即在非virtual析构函数的情况下)。