ARM C ++ ABI:构造函数/析构函数的返回值 [英] ARM C++ ABI: Constructor/destructor return values

查看:285
本文介绍了ARM C ++ ABI:构造函数/析构函数的返回值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在读通过锵源$ C ​​$ c和发现了一些有趣的关于ARM C ++ ABI,我似乎无法理解的理由。从 ARM ABI文档:

I've been reading through Clang source code and discovered something interesting about the ARM C++ ABI that I can't seem to understand the justification for. From the an online version of the ARM ABI documentation:

这ABI需要C1和C2构造函数返回的这个的(而不是被无效的功能),使得C3构造
  可以尾部调用构造函数C1和C1构造函数可以尾调用C2。

This ABI requires C1 and C2 constructors to return this (instead of being void functions) so that a C3 constructor can tail call the C1 constructor and the C1 constructor can tail call C2.

(同样非虚析构函数)

我不知道是什么 C1 C2 C3 此处参考。这一节,就是要的§3.1.5从一般的(即安腾)ABI的修改,而这部分(至少在的这个网上verison )只是规定:

I'm not sure what C1, C2, and C3 reference here...this section is meant to be a modification of §3.1.5 from the generic (i.e. Itanium) ABI, but that section (at least in this online verison) simply states:

构造函数返回的无效的结果。

Constructors return void results.

不管怎样,我真的想不出什么这样做的目的是:如何做一个构造函数返回的这个的允许尾部调用优化,以及在什么情况下

Anyway, I really can't figure out what the purpose of this is: how does making a constructor return this allow tail call optimization, and in what circumstances?

据我所知道的,只是时间的构造可以尾巴调用另一个相同这个返回值将是一个派生类具有一个基类的情况下,一个简单的构造体,具有非平凡的构造函数没有成员,也没有虚表指针。事实上,它看起来像它实际上是更容易,而不是更辛苦,用一个无效回尾调用优化,因为那时一个基类的限制可能是淘汰(在多基类的情况下,从上称为构造函数返回的不会是这个指针这个指针派生的对象)。

As far I can tell, the only time a constructor could tail call another with the same this return value would be the case of a derived class with a single base class, a trivial constructor body, no members with non-trivial constructors, and no virtual table pointer. In fact, it seems like it would actually be easier, not harder, to optimize with a tail call with a void return, because then the restriction of a single base class could be eliminated (in the multiple base class case, the this pointer returned from the last called constructor will not be the this pointer of the derived object).

我缺少的是在这里吗?是否有一些关于ARM调用约定,使这个返回有必要吗?

What am I missing here? Is there something about the ARM calling convention that makes the this return necessary?

推荐答案

好吧,从@迈克尔有用的链接做这一切都清楚...... C1 C2 C3 请参阅完整对象的构造,基础对象的构造函数和完整对象的名称,识别码分别分配构造函数,从安腾ABI:

Ok, helpful link from @Michael made this all clear...C1, C2, and C3 refer to the name-mangling of the "complete object constructor", "base object constructor", and "complete object allocating constructor", respectively, from the Itanium ABI:

  <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 /完整的对象分配的构造函数,是构造一个版本,而不是通过这个参数,内部分配内存(通过运营商新的),然后调用 C1 /完成对象的构造,这是用于完整的对象的情况下正常的构造函数。因为 C3 构造必须返回这个指向新分配和构造的对象,在 C1 构造函数也必须返回这个指针为了要使用的尾调用。

The C3/"complete object allocating constructor" is a version of the constructor that, rather than operating on already allocated storage passed to it via the this parameter, allocates memory internally (via operator new) and then calls the C1/"complete object constructor", which is the normal constructor used for the complete object case. Since the C3 constructor must return the this pointer to the newly allocated and constructed object, the C1 constructor must also return the this pointer in order for a tail call to be used.

C2 /基地对象的构造,是通过构建一个基类子对象时,派生类称为构造函数; C1 C2 构造中的情况下,不同的虚拟继承并且可以不同的方式实现优化的目的也是如此。在虚拟继承的情况下,一个 C1 构造可以与调用来实施虚拟基类的构造函数后面尾调用到 C2 的构造函数,因此后者也应该返回这个如果以前一样。

The C2/"base object constructor" is the constructor called by derived classes when constructing a base class subobject; the semantics of C1 and C2 constructors differ in case of virtual inheritance and could be implemented differently for optimization purposes as well. In the case of virtual inheritance, a C1 constructor could be implemented with calls to virtual base class constructors followed by a tail call to a C2 constructor, so the latter should also return this if the former does.

析构函数的情况是略有不同但相关的。根据ARM的ABI:

The destructor case is slightly different but related. As per the ARM ABI:

同样,我们需要D2和D1回到这个让D0不需要保存和恢复的这个的和D1可以尾部调用D2(如果没有虚基类)。 D0仍然是一个空白的功能。

Similarly, we require D2 and D1 to return this so that D0 need not save and restore this and D1 can tail call D2 (if there are no virtual bases). D0 is still a void function.

D0 /删除析构函数删除对象时使用,它调用 D1 /完成对象的析构,并呼吁 delete操作符这个指针事后释放内存。具有 D1 的析构函数返回这个允许 D0 析构函数使用其返回值来调用 delete操作符,而不是将它保存到另一个寄存器或溢出到内存中;同样, D 2 /基地对象的析构应该返回这个以及

The D0/"deleting destructor" is used when deleting an object, it calls the D1/"complete object destructor" and calls operator delete with the this pointer afterwards to free the memory. Having the D1 destructor return this allows the D0 destructor to use its return value to call operator delete, rather than having to save it to another register or spill it to memory; similarly, the D2/"base object destructor" should return this as well.

在ARM ABI还增加了:

The ARM ABI also adds:

我们不要求thunks来虚析构函数返回的这个的。这样一个thunk将不得不调整析构函数的
  因此,$ P $从尾pventing它调用析构函数,和作废任何可能的节省。

We do not require thunks to virtual destructors to return this. Such a thunk would have to adjust the destructor’s result, preventing it from tail calling the destructor, and nullifying any possible saving.

因此​​,D1和D2析构函数的唯一的非虚拟调用可以依靠返回的这个

Consequently, only non-virtual calls of D1 and D2 destructors can be relied on to return this.

如果我理解这个正确的,那就意味着这个保存 - 恢复 - 省音优化只能用在 D0 通话 D1 静态(即非的情况 - 虚拟的析构函数)。

If I understand this correctly, it means that this save-restore-elision optimization can only be used when D0 calls D1 statically (i.e. in the case of a non-virtual destructor).

这篇关于ARM C ++ ABI:构造函数/析构函数的返回值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆