![]() |
1
12
当函数被调用时,该函数必须返回一个值。该值需要内存才能生存,但返回值需要超过函数本身。ABI定义了这一切是如何工作的。一般来说,这是通过调用方为函数的返回值提供一块大小/对齐方式的内存来实现的。 因此,如果一个函数计算一个值并返回它,它必须(理论上)将计算的值复制到返回值内存中。当调用者检索它时,它必须(理论上)将返回值内存复制到其他堆栈对象中,以便以后使用。 无担保的副本省略表示这些副本都不是必需的。在返回函数方面,允许编译器在生成返回值时在内部简单地使用返回值内存,因此return语句不必复制任何内容。在接收端,如果内存将用于初始化堆栈对象,则它不必复制到该内存中。
有保证的复制省略表示,如果接收方正在初始化同一类型的对象,那么接收方将不会考虑该对象是否具有复制/移动构造函数。因此,调用如下函数的代码
在被调用方,如果直接返回prvalue,则不需要存在复制/移动构造函数。被调用方将直接在返回值内存中构造prvalue。 事情是这样的:ABI根本不在乎这些。ABI关心的只是低级内存。也就是说,只要调用者传递的是适当大小和对齐方式的返回值内存,并且被调用者使用适当类型的对象初始化该内存……ABI 不在乎 . 如果调用者希望在以后的操作中使用返回值内存,那么ABI就可以了。如果被调用者希望将数据直接初始化到返回值内存中,而不是复制它,ABI不会注意到。 ABI定义了接口;如何使用该接口取决于您。 例如,考虑 Itanium ABI on return values 它允许类类型存储在寄存器中,但 只有 如果它们有微不足道的复制/移动构造函数。否则,无论其内容如何,它们都必须在调用函数提供的内存中构造。如果类是普通的可复制类,那么您就无法区分省略和非省略。 ABI对该特性造成问题的唯一方式是,ABI是否任意决定返回值(以及参数)的存储位置,它们之间是否相互关联。也就是说,ABI强制调用者将对象放在堆栈上相对于参数的特定位置。 这样的ABI会存在吗?我没有特别的知识可以说它不能。是吗?我对此表示怀疑,因为这样的ABI通常会使省略变得相当困难。 |
![]() |
AstralHex · 矩阵乘法代码工作不正常 5 月前 |
![]() |
Fishie · 作为类成员的智能指针是否仍然自动释放?[关闭] 5 月前 |
![]() |
Die4Toast · 递归调用成员箭头运算符-> 5 月前 |
![]() |
Anka Hanım · 关于结构和动态数组地址的问题 5 月前 |