问题描述
函数的返回值通常被存储在堆栈或寄存器。但对于一个大的结构,它必须是在堆栈中。多少复制在此code真正的编译器发生呢?抑或是优化掉?
The return value of a function is usually stored on the stack or in a register. But for a large structure, it has to be on the stack. How much copying has to happen in a real compiler for this code? Or is it optimized away?
例如:
struct Data {
unsigned values[256];
};
Data createData()
{
Data data;
// initialize data values...
return data;
}
(假设不能被内联函数..)
(Assuming the function cannot be inlined..)
推荐答案
无;不需要拷贝。
呼叫者的数据返回值的地址实际上是作为隐藏参数传递给函数,而createData函数只是写入到调用者的堆栈帧。
The address of the caller's Data return value is actually passed as a hidden argument to the function, and the createData function simply writes into the caller's stack frame.
这就是所谓的。另见本专题中的 C ++ FAQ。
This is known as the named return value optimisation. Also see the c++ faq on this topic.
商业级的C ++编译器实现的方式,让他们消除了开销,收益按值至少在简单的情况下
...
当您的code()调用RBV(),编译器偷偷将指针传递到RBV()假设来构造的位置返回对象。
When yourCode() calls rbv(), the compiler secretly passes a pointer to the location where rbv() is supposed to construct the "returned" object.
您可以证明,这是通过添加一个析构函数与一个printf你做的结构。如果该返回按值的优化是在操作中,否则两次析构应该只被调用一次。
You can demonstrate that this has been done by adding a destructor with a printf to your struct. The destructor should only be called once if this return-by-value optimisation is in operation, otherwise twice.
你也可以检查装配一看就知道发生什么:
Also you can check the assembly to see that this happens:
Data createData()
{
Data data;
// initialize data values...
data.values[5] = 6;
return data;
}
这里的集会:
__Z10createDatav:
LFB2:
pushl %ebp
LCFI0:
movl %esp, %ebp
LCFI1:
subl $1032, %esp
LCFI2:
movl 8(%ebp), %eax
movl $6, 20(%eax)
leave
ret $4
LFE2:
奇怪的是,它在栈中的数据项 subl $ 1032%ESP
,但要注意,它需要在堆栈上的第一个参数<$ C $在分配足够的空间C> 8(%EBP)作为对象的基地址,然后初始化该项目的元件6。由于我们没有指定任何参数createData,直到你意识到这是秘密藏指针数据的父母的版本,这是奇怪的。
Curiously, it allocated enough space on the stack for the data item subl $1032, %esp
, but note that it takes the first argument on the stack 8(%ebp)
as the base address of the object, and then initialises element 6 of that item. Since we didn't specify any arguments to createData, this is curious until you realise this is the secret hidden pointer to the parent's version of Data.
这篇关于如何C编译器实现返回大的结构功能呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!