gpt4 book ai didi

c++ - return 语句是否为按值返回的函数创建一个临时对象?

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

在学习 C++11 右值引用和移动语义时,我开始对函数究竟如何返回值来初始化变量感到困惑。看下面的例子:

Widget makeWidget()
{
Widget w;

return w;
}
Widget w1 = makeWidget();

这里我假设没有 RVO(即编译不会省略复制/移动)。当执行返回语句return w;时,执行函数:

1) 在众所周知的位置(调用者知道的某个固定寄存器或内存位置)复制初始化一个临时对象,其值成为函数的返回值?然后调用者获取这个对象来复制初始化w1?或者

2) 函数获取w1的调用者传递的内存位置,函数的自动变量w用于复制初始化w1? (这已经是某种 RVO 了吗?还是某种内联函数行为?或者它是一种可能的调用约定?)

如果是第一种情况,并且 return 创建了一个临时文件,则将有两次复制构造函数调用,一次创建临时文件,一次创建 w1。如果是第二种情况,将只有一个复制构造函数调用来创建 w1

现在假设我们有 RVO。那么如果 return 的行为是 case 1),那么编译器可以通过直接在众所周知的返回值位置构造 w 来省略临时的复制构造。如果 return 的行为类似于 case 2),那么在这种情况下,RVO 甚至可以在分配给 w1 的内存位置直接创建自动变量 w .我对 RVO 的理解是否正确?


现在让我添加移动语义。再次假设,没有 RVO,看下面的例子:

Widget makeWidget()
{
Widget w;

return std::move(w);
}
Widget w1 = makeWidget();

现在再次针对上述两种情况:

1) 我是否希望有两个 Action :第一步是使用表达式 std::move(w) 初始化临时 Widget 对象;第二步是用右值的临时 Widget 初始化 w1?或者

2) 只有一个 Action :用表达式 std::move(w) 初始化 w1 ?


最后一个问题:返回行为是否取决于它返回的是 POD 类型还是类类型?

最佳答案

1) copy initialize a temporary object, whose value becomes the function's return value, in a well known location (some fixed register or memory location that caller knows)? Then caller fetches this object to copy initialize w1?

大致就是这样。通常,调用者分配必要的堆栈空间来保存返回值,并将指向它的指针作为隐藏参数传递。

请注意,两个复制初始化实际上都是移动。

then compiler can elide the [...] construction of the temporary, by constructing w directly in the well known location for return value.

对(但这是一步棋)。并且它可以通过传递其地址作为应该构造返回值的位置来进一步省略 w1 的构造。

Widget makeWidget()
{
Widget w;

return std::move(w);
}
Widget w1 = makeWidget();

这是一个不可省略的移动(从 std::move(w) 到临时返回值)和一个可删除的移动(从临时返回值到 w1).

does the return behavior depend on whether it returns a POD type or a class type?

可以。根据平台 ABI,一些小型 POD 类型可能会在寄存器中返回。

关于c++ - return 语句是否为按值返回的函数创建一个临时对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32409925/

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