gpt4 book ai didi

c - C 编译器如何实现返回大型结构的函数?

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:37:48 27 4
gpt4 key购买 nike

函数的返回值通常存储在堆栈或寄存器中。但是对于大型结构,它必须在堆栈上。在真正的编译器中必须为此代码进行多少复制?还是优化掉了?

例如:

struct Data {
unsigned values[256];
};

Data createData()
{
Data data;
// initialize data values...
return data;
}

(假设函数不能内联..)

最佳答案

无;没有副本完成。

调用者的 Data 返回值的地址实际上作为隐藏参数传递给函数,createData 函数只是简单地写入调用者的堆栈帧。

这被称为 named return value optimisation .另见 c++ faq on this topic .

commercial-grade C++ compilers implement return-by-value in a way that lets them eliminate the overhead, at least in simple cases

...

When yourCode() calls rbv(), the compiler secretly passes a pointer to the location where rbv() is supposed to construct the "returned" object.

您可以通过将带有 printf 的析构函数添加到您的结构来证明这已完成。如果此按值返回优化正在运行,则应仅调用一次析构函数,否则调用两次。

您还可以检查程序集以查看是否发生了这种情况:

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 分配了足够的空间,但请注意它采用堆栈上的第一个参数 8(%ebp) 作为对象的基地址,然后初始化该项目的元素 6。由于我们没有为 createData 指定任何参数,这很奇怪,直到您意识到这是指向父数据版本的 secret 隐藏指针。

关于c - C 编译器如何实现返回大型结构的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58439905/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com