我大致了解函数如何按值返回对象。但我想在较低的层次上理解它。装配水平(如果合理)。
我理解这段代码
ClassA fun(){
ClassA a;
a.set(...);
return a;
}
内部转换为
void fun(Class& ret){
ClassA a;
a.set(...);
ret.ClassA::ClassA(a);
}
这有效地调用了返回值上的复制构造函数。
我也知道有一些优化(如 NRVO)可以生成以下代码以避免复制构造函数。
void fun(Class& ret){
ret.set(...);
}
但是我的问题有点基础。它实际上与特定对象无关。它甚至可以是原始类型。
假设我们有这段代码:
int fun(){
return 0;
}
int main(){
fun();
}
我的问题是返回对象存储在内存中的什么位置。
如果我们看栈...有main
的栈帧,然后是fun
的栈帧。返回对象是否存储在某个地址中,比如两个堆栈帧之间?或者它可能存储在 main
堆栈帧中的某处(并且可能是在生成的代码中通过引用传递的地址)。
我已经考虑过了,第二个似乎更实用,但是我不明白编译器如何知道要在 main
的堆栈帧中压入多少内存?它是否会计算最大的返回类型并推送它,即使可能会浪费一些内存?或者它是动态完成的,它仅在调用函数之前分配该空间?
最佳答案
C++ 语言规范没有指定这些底层细节。它们由每个 C++ 实现指定,实际实现细节因平台而异。
几乎在每种情况下,一个简单的 native 类型的返回值都会返回到某个指定的 CPU 寄存器中。当一个函数返回一个类实例时,细节因实现而异。有几种常见的方法,但典型的情况是调用者负责在堆栈上为返回值分配足够的空间,然后调用函数并将额外的隐藏参数传递给函数,函数将在其中复制返回值(或构造它,在 RVO 的情况下)。或者,参数是隐式的,并且函数可以在调用的堆栈帧之后在堆栈上为返回值本身找到空间。
也有可能给定的 C++ 实现仍将使用 CPU 寄存器来返回足够小以适合单个 CPU 寄存器的类。或者,也许,一些 CPU 寄存器被保留用于返回稍大的类。
细节各不相同,您需要查阅 C++ 编译器或操作系统的文档,以确定适用于您的具体细节。
关于c++ - 返回对象存储在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41910764/