c++函数如何返回一个大对象或结构?
How do C++ functions return a big object or a structure?
我在《计算机系统》中读到一个程序员的观点,当一个人用汇编代码编程时,关于调用者-被调用者协议的约定声明函数的返回值应该存储在eax
(或64位计算机中的模拟rax
)寄存器中。
我猜这是在C编程时自动发生的"幕后",这意味着C编译器"知道"使用eax
寄存器的函数返回值。
但是在c++中,当返回值是一个不适合32位eax
或64位rax
寄存器的大对象时会发生什么?显然你不能使用堆栈传递这个,那么编译器如何处理一个大对象的按值返回操作呢?
别管一个大对象,C编译器如何处理一个大结构体的按值返回?
是否将其保存在临时内存空间中并返回其地址作为返回值?如果是这样,它必须预测在运行期间要对函数进行多少次调用,有时这是不可能的,不是吗?
显然你不能用堆栈传递这个
实际上,理论是,每当调用函数并且它的堆栈帧被容纳时,它也会为返回对象腾出空间。然后由调用函数来确保返回值在它自己的堆栈帧内的某个地方被复制,以便它可以保存它。
这直接对应于C和c++中的工作方式。您有一个return ...;
语句,它将一些值复制到返回对象中。返回对象是一个临时对象,因此调用代码必须将其存储在某个地方,例如int value = foo();
。
然而,几乎从来没有必要为返回值保留空间。相反,调用函数为它腾出空间,被调用函数将返回值直接放在那里。这正是返回值优化和复制省略所代表的内容。
显然你不能用堆栈
传递这个
你可以!诀窍是让调用者在堆栈上分配空间,并让函数填充它。
本质上,该函数返回堆栈帧中调用方部分的数据。
您应该想象函数的返回值像局部变量一样放在堆栈上。而且,像局部变量一样,这可以被优化(并且有一些约定取决于体系结构,这些体系结构规定了良好定义的行为),以便小的返回值进入寄存器而不是堆栈。
- 为什么我不能将一个对象push_back到属于另一个类的对象向量中?
- 在他自己的方法中,有可能将一个对象取消引用到另一个对象吗
- 从多个源构造一个对象,包括一个对象向量
- 为什么C++在将一个对象复制到另一个对象时需要对这两个对象进行低级常量限定
- 检查哪个对象调用了另一个对象的对象方法
- C++ 如何在将新对象分配给另一个对象时创建新对象
- 如何处理从一个对象传递到另一个在C++中具有公共抽象类的对象的消息
- 我有一个对象,它将在整个程序的持续时间内实例化,但一个类成员不会,我应该动态分配它吗?
- 包装一个对象并假装它是一个 int
- 为什么我可以在不重载 "=" 运算符的情况下将一个对象分配给另一个对象?
- 如何在qt中将信号和插槽与另一个对象连接 --解决了
- 如何使用函数将一个对象的输入复制到另一个对象中
- 选择一个元素而不是一个对象的数组的原因
- 为什么我可以使用 memcpy 将一个对象变量复制到另一个对象变量
- 如何将包含另一个对象向量的对象保存到文件中,并使用C++中的二进制文件从文件中读回?
- 我重载了 << 和 = 运算符。为什么当我将一个对象分配给另一个对象并尝试打印它时,我会被打印出来?
- 打印对象的映射,其中另一个对象作为键
- 如何通过另一个对象中的命令正确地从一个对象返回数据
- 为什么将两个对象分配给另一个对象后,两个对象不一样?
- 绘制一个对象,比较模具缓冲区的两个不同值