在没有 RVO 的情况下返回类/结构时会发生什么?
What happens when a class/struct is returned WITHOUT RVO?
我知道 RVO 通常是可取的,但是当它无法应用时会发生什么?具体来说,生成的程序集代码如何将本地类/结构实例返回给其调用方?
MyClass callee() {
MyClass a;
/* RVO is disabled */
return a;
}
void caller() {
/* RVO is disabled */
MyClass b = no_rvo();
}
在这种情况下,堆栈是什么样子的?caller()
和callee()
是否分别为堆栈上的a
和b
分配空间,然后将a
复制到b
?如果是这样,callee()
末尾的 RET 语句是将堆栈指针完全减少到以前的状态,还是在复制操作后释放a
堆栈内存?
这取决于调用约定。 但是所有 x86 32 位和 64 位调用约定都做出相同的选择,并将指向返回值的指针作为"隐藏"的第一个参数传递。
callee
仍然可以优化a
(除非其他事情阻止这种情况发生),并直接存储到该返回值指针中。
不可复制的类型可能需要在某个时候运行复制构造函数,以及用于a
的析构函数。
但是回复:您的实际问题,启用优化后,调用方将传递&b
作为返回值指针。
禁用优化后,我想我已经看到一些编译器为单独的临时返回值创建空间,然后从那里复制,这对于可复制的类型来说是非常多余的。
理论上,返回值指针可以指向堆栈内存以外的其他位置,例如,如果分配给static MyClass arr[10]
的元素。
但它不能指向callee
可以通过任何其他方式访问的任何内容,因为在C++抽象机器中,返回值是一个单独的对象,在函数返回之前没有任何内容可以指向它。
相关文章:
- 有什么方法可以遍历结构吗
- 在 c++ 中拥有一组结构的正确方法是什么?
- "perf_event_attr"结构的"read_format"属性的选项到底是什么?
- C++中deque数据结构的大O是什么?
- 在什么情况下,两个堆栈分配的结构对象的 this 点指向同一个地址?
- 将信息输入到下面显示的结构向量中的正确语法/格式是什么
- 不同的类或结构初始化方法之间的性能差异是什么?
- 结构块指的是什么?
- 让编译器告诉什么确切的纯虚拟方法使结构抽象?
- C++ 类层次结构中的"对齐"是什么意思?
- 自定义数据结构的优点是什么?
- 如果结构中的字符串比使用的 p/调用签名长或短,会发生什么情况?
- 我的堆栈和库存清单程序的结构有什么问题?
- 将此私有删除器函数包装在结构中的目的是什么?
- 在只读(即 const)访问器上执行结构化绑定的最佳实践是什么?
- 清除结构向量时会发生什么?
- 这里的以下 OOP 结构是什么?
- 用于筛子的最佳数据结构是什么(即一些被划掉的数字列表)?
- 将一种数据类型的向量复制到同一数据类型的结构向量中的有效方法是什么
- 当C++类函数参数之一是结构时,它们的语法有什么不同