gpt4 book ai didi

c++ - 返回值优化的魔力是什么?

转载 作者:行者123 更新时间:2023-11-30 01:37:28 46 4
gpt4 key购买 nike

基本上,我正在做的事情如下。我的 D 类具有三个构造函数(默认、移动、复制)和两个重载赋值运算符(移动和复制)。我希望任何 D 类型对象的创建都将调用至少五个中的一个。

但是,如下创建 D 对象“d4”不会调用它们中的任何一个:

D d4( foo() );  // foo returns a D

这是重现我想知道的问题的代码:

#include <iostream>
#include <vector>
#include <cassert>
using std::cout;
using std::endl;
class D {
public:
D()
{ cout << "D default"<<endl;}

D(const D& d)
{
cout << "D copy" << endl;
}

D(D&& d)
{
cout << "D rval" << endl;
assert(0);
}

D& operator=(D&& d)
{
cout << "D mv assign" << endl;
return *this;
}

D& operator=(const D& d)
{
cout << "D copy assign" << endl;
return *this;
}

volatile int v;
};

// return
D foo()
{
D res;
cout <<"returning a non const D" << endl;
return res;
}

int main()
{
D d4(foo());

return 0;
}

基本上,我假设 D(D&& d) 将被调用以创建 d4,因为 foo() 返回一个临时地址,其地址可能不会被占用。实际上,只有当返回值优化被 -fno-elide-constructors 禁用时,情况才会如此。

但是,如果未指定,即使在 -O0 上,RV 优化也会默认打开。然后,我看到的是这样的:

D default
returning a non const D

我从标准输出中看到的所有内容都来自 foo()。 d4 本身的创建没有给我任何帮助。这与我的预期不同。

我期待以下内容。返回值的内存空间分配在调用者的堆栈中,而不是被调用者的堆栈中。调用默认构造函数来访问内存空间。从被调用者的堆栈到调用者的堆栈不会发生复制。之后,另一个内存空间被分配到调用者的堆栈中。由于返回值是一个右值,因此调用移动构造函数以在“调用者堆栈中的另一个内存空间”上写入一些内容。

我知道这可能需要冗余内存空间。但是,特别是在我的示例中,移动构造函数将因 assert(0) 而终止。任何构造函数,但它会让程序继续。结果,返回值优化在程序输出方面产生了差异。

这是预期的吗?如果有,背后的原因是什么?我已经测试了 g++-7.3.0 和 clang++-5.0.1。他们是一样的。

最佳答案

因为您使用 C++17,它 promise RVO,即使您添加了 -O0。 this maybe help

关于c++ - 返回值优化的魔力是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49693452/

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