返回值优化的步骤

发布于 2024-12-24 01:11:20 字数 1010 浏览 2 评论 0原文

可能的重复:
了解返回值优化和返回临时值 - C++

Integer 是某个以 i 作为成员的类。leftright 作为参数传递给函数调用,并且是type Integer

现在如 Bruce Eckel 中给出的那样。

代码 1:

return Integer(left.i+right.i);

代码 2:

Integer tmp(left.i+right.i);
return tmp;

代码 1 表示创建一个临时整数对象并返回它,它与创建一个命名局部变量并返回它不同,这是一个普遍的误解。

在代码 1 中(称为返回临时方法):
编译器知道您不需要它正在创建的对象,然后将其返回。编译器通过将对象直接构建到外部返回值的位置来利用这一点。这仅需要一个普通的构造函数调用(无复制构造函数),并且不需要析构函数,因为没有创建本地对象。

代码 2 中会发生 3 件事:
a) 创建 tmp 对象,包括其构造函数调用
b) 复制构造函数将 tmp 复制到外部返回值的位置
c) 在作用域末尾为 tmp 调用析构函数。

在代码 1 中,这意味着什么:将对象直接构建到外部返回值的位置
另外为什么代码 1 中不会调用复制构造函数?

我也不明白代码2中的步骤b在做什么?即复制构造函数将 tmp 复制到外部返回值的位置

Possible Duplicate:
Understanding return value optimization and returning temporaries - C++

let Integer be some class with i as it's member.left and right are passed as arguments to a function call and are of type Integer

Now as given in Bruce Eckel.

Code 1:

return Integer(left.i+right.i);

Code 2:

Integer tmp(left.i+right.i);
return tmp;

code 1 says make a temporary integer object and return it and it is different from creating a named local variable and returning it,which is a general misconception.

In Code 1(called as returning a temporary approach):
The compiler knows that you have no other need for the object it's creating then to return it.The compiler takes advantage of this by building the object directly into the location of the outside return value. This requires only a single ordinary constructor call(no copy-constructor) and no destructor is required as no local object was created.

While 3 things will happen in code 2:
a) tmp object is created including its constructor call
b) the copy-constructor copies the tmp to the location of the outside return value.
c) the destructor is called for tmp at the end of scope.

In code 1 what does this mean : building the object directly into the location of the outside return value ?
also why copy constructor will not be called in code 1 ?

Also I didn't understand what does step b in code 2 is doing ? i.e.the copy-constructor copies the tmp to the location of the outside return value.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

予囚 2024-12-31 01:11:20

编译器可以自由地优化按值传递按值返回的复制构造函数。我的猜测是,任何像样的优化器都会为这两个变体生成相同的二进制文件。

代码的优化版本:

A foo()
{
   A temp;
00401000  mov         ecx,dword ptr [A::x (40337Ch)] 
00401006  mov         dword ptr [eax],ecx 
00401008  add         ecx,1 
0040100B  mov         dword ptr [A::x (40337Ch)],ecx 
   return temp;
}

所以你看,复制构造函数没有被调用,尽管在我的版本中,它有一个cout,所以它确实影响了观察到的行为。

没有优化:

A foo()
{
004113C0  push        ebp  
004113C1  mov         ebp,esp 
004113C3  sub         esp,0CCh 
004113C9  push        ebx  
004113CA  push        esi  
004113CB  push        edi  
004113CC  lea         edi,[ebp-0CCh] 
004113D2  mov         ecx,33h 
004113D7  mov         eax,0CCCCCCCCh 
004113DC  rep stos    dword ptr es:[edi] 
   A temp;
004113DE  lea         ecx,[temp] 
004113E1  call        A::A (4110E6h) 
   return temp;
004113E6  lea         eax,[temp] 
004113E9  push        eax  
004113EA  mov         ecx,dword ptr [ebp+8] 

/// copy constructor called on next line:

004113ED  call        A::A (411177h) 
004113F2  mov         eax,dword ptr [ebp+8] 
}

短语“b)复制构造函数将 tmp 复制到外部返回值的位置。”这是牵强的,有时甚至不会发生。

您应该记住的是,您不应该依赖于被调用的复制构造函数。

The compiler is free to optimize out copy constructors for pass-by-value and return-by-value. My guess is that any decent optimizer will generate the same binary for both variants.

An optimized version of the code:

A foo()
{
   A temp;
00401000  mov         ecx,dword ptr [A::x (40337Ch)] 
00401006  mov         dword ptr [eax],ecx 
00401008  add         ecx,1 
0040100B  mov         dword ptr [A::x (40337Ch)],ecx 
   return temp;
}

So you see, the copy constructor is not called, even though, in my version, it has a cout, so it does influence observed behavior.

Without optimization:

A foo()
{
004113C0  push        ebp  
004113C1  mov         ebp,esp 
004113C3  sub         esp,0CCh 
004113C9  push        ebx  
004113CA  push        esi  
004113CB  push        edi  
004113CC  lea         edi,[ebp-0CCh] 
004113D2  mov         ecx,33h 
004113D7  mov         eax,0CCCCCCCCh 
004113DC  rep stos    dword ptr es:[edi] 
   A temp;
004113DE  lea         ecx,[temp] 
004113E1  call        A::A (4110E6h) 
   return temp;
004113E6  lea         eax,[temp] 
004113E9  push        eax  
004113EA  mov         ecx,dword ptr [ebp+8] 

/// copy constructor called on next line:

004113ED  call        A::A (411177h) 
004113F2  mov         eax,dword ptr [ebp+8] 
}

The phrase "b) the copy-constructor copies the tmp to the location of the outside return value." is far-feched, sometimes even that doesn't happen.

What you should remember from this is that you shouldn't rely on copy-constructors being called.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文