return语句是否为按值返回的函数创建一个临时对象? [英] Does return statement create a temporary object for functions returning by value?

查看:252
本文介绍了return语句是否为按值返回的函数创建一个临时对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我学习C ++ 11右值引用并移动语义时,我开始对函数如何返回值以初始化变量的确切方法感到困惑。看下面的例子:

As I am learning C++11 rvalue references and move semantics, I start to feel confused about exactly how function returns a value to initialize a variable. Look at the following example:

Widget makeWidget()
{
    Widget w;
    …
    return w;
}
Widget w1 = makeWidget();

在这里,我假设没有RVO(即,编译不会忽略复制/移动)。当执行return语句 return w; 时,执行以下功能:

Here I assume no RVO (i.e., the compile won't elide copy/move). When executing the return statement return w;, does the function:

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

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? Or

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

2) the function gets the caller-passed memory location of w1 and the function's automatic variable w is used to copy initialize w1? (Is this some sort of RVO already? Or some sort of inline function behavior? Or it is a possible calling convention?)

如果是第一种情况,则返回创建一个临时文件,将有两个副本构造函数调用,一个创建临时文件,一个创建 w1 。如果是第二种情况,将只有一个副本构造函数调用来创建 w1

If it is the first case, and return creates a temporary, there would be two copy constructor calls, one creating the temporary, one creating w1. If it is the second case, there would be only one copy constructor call to create w1.

现在假设我们有RVO。然后,如果返回的行为是案例 1),则编译器可以通过直接在众所周知的位置构造 w 来消除临时副本的构造返回值的位置。如果返回的行为类似于情况 2),那么在这种情况下,RVO甚至可以直接在分配给<$的内存位置中创建自动变量 w c $ c> w1 。我对RVO的理解正确吗?

Now assume we have RVO. Then if the behavior of return is case 1), then compiler can elide the copy construction of the temporary, by constructing w directly in the well known location for return value. If return behaves like case 2), then RVO, in this case, can even create automatic variable w directly in the memory location allocated for w1. Is my understanding for RVO correct?

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

Now let me add move semantics in. Assume again, there is no RVO, and look at the following example:

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

对于以上两种情况,现在再次:

Now again for the two cases above:

1):我是否希望有两个动作:第一个动作来自初始化临时 Widget 对象的表达式 std :: move(w);第二步是通过使用临时值 Widget 初始化 w1 来实现的?或

1) do I expect two moves: first move comes from initializing the temp Widget object with expression std::move(w); second move comes from initializing w1 with the temp Widget which is a rvalue? OR

2)只有一招:用表达式<初始化 w1 code> std :: move(w)?

2) there is only one move: initializing w1 with the expression std::move(w) ?

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

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

推荐答案


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

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?

大致如此。通常,调用方分配必要的堆栈空间来保存返回值,并将指针作为隐藏参数传递给它。

Roughly this. Usually, the caller allocates the necessary stack space to hold the return value and pass a pointer to it as a hidden argument.

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

Note that both copy-initializations are actually moves.


然后,编译器可以通过
构造 w来消除临时结构直接在返回值的知名位置。

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

对(但这是一个举动)。通过传递其地址作为应构造返回值的位置,它可以进一步消除 w1 的构造。

Right (but it's a move). And it can further elide the construction of w1 by passing its address as the location at which the return value should be constructed.


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


这是一项不可逾越的举措(来自 std :: move(w)到临时返回值)和一个可忽略的移动(从临时返回值到 w1 )。 / p>

This is one non-elidable move (from std::move(w) to the temporary return value) and one elidable move (from the temporary return value to w1).


返回行为取决于返回的是POD类型还是
类类型?

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

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

It can. Depending on the platform ABI, some small POD types may be returned in registers.

这篇关于return语句是否为按值返回的函数创建一个临时对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆