栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++——关于返回值优化问题

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++——关于返回值优化问题

我们知道,对于一个函数的返回值来说,其是一个对象的拷贝。并且应当是一个右值。我们现在有一个函数

A get_A()
{
    A a(1);
    return a;
}

int mian()
{
    A = get_A();
    return 0;
}

这个函数的行为应当是在函数体中构造一个a,然后在返回的时候再复制一份a。

我们的本意是仅仅的得到一份a,但是却做了重复的拷贝工作。在编译器还不是那么智能的年代,这个问题不能得到很好的解决。但是现代C++中,编译器会为我们做优化。我们如上调用这个函数,编译器我们生成的目标代码就像是直接调用了A的构造函数一样。

struct A
{
    int data;
    A() : data(0)
    { 
        cout << "construction" << endl;
    }
    A(int d) : data(d)
    {
        cout << "construction" << endl;
    }
    A(A && a) : data(a.data)
    {
        cout << "move" << endl;
    }
    A(const A & a) : data(a.data)
    {
        cout << "copy con" << endl;
    }
    ~A()
    {
        cout << "destruction" << endl;
    }
};
A get_A()
{
    A a(1);
    return a;
}
A get_A_p()
{
    return A(1);
}

int main()
{
    A a1 = get_A();
    // A a2 = get_A_p()
    cin.get();
    return 0;
}

你可以拿着这么一个简短的代码去g++, 或者clang++,或者是任何一个支持返回值优化的编译上去运行,你将会得到如下的结果。

所以说,如果有编译器的优化,在些C++代码的时候关于返回值这里可以放心的去写。效率的工作编译器为我们承担了一部分。


不过为读者困惑的是,即便关闭了编译器优化,我么得到的目标文件还是可以进行返回值优化,如果想要关闭这种优化来看一下返回值具体的运作过程,需要使用以下的命令。

 g++ main.cpp -o main -fno-elide-constructors

运行程序

 

这是一个惊人的结果!如果在对象比较大的时候还没有对应的移动构造,那么进行的无用复制可想而知。

来分析以下:

首先是函数内的A a(1) 对象,返回值用其移动构造,然后a自身销毁,返回值又移动构造给了main中的a1然后销毁。这个开销还是很大的。不过好在有编译器为我们优化,在现代C++设计中,有编译器的优化,我们可以不用在返回值的效率上杞人忧天了,岂不是十分舒服!

参考:

More Effective C++条款19,20

 g++ 关闭返回值优化_天涯Kevin的博客-CSDN博客_g++ 关闭优化

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/953669.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号