文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>编译器对临时变量的优化--简单理解

编译器对临时变量的优化--简单理解

时间:2010-08-21  来源:烛秋

编译器对临时变量的优化--简单理解

2010-7-6

烛秋

2010-8-20整理

一、问题来源

  之前对NRV优化做了一点总结,还有所欠缺,只分析了 A b = f();的情况,没有去分析A b; b = f();的情况。又想起之前看过的书,对产生临时对象的讲解都是假设了编译器没有进行优化,然后说要提高C++程序性能,必须尽量的少使用返回对象,因为那样才不会产生临时对象。多使用引用/指针可以减少临时对象的产生,提高程序性能,这个观点没有错。但事实上很多编译器多做了优化,使得临时对象的产生减少了很多,打算以最简单的例子对编译器的优化做简单的理解。

代码:

/*
*/
/////////////////////////////////////////////////
/*
*命令行编译:
*g++ -o 1.exe 1.cpp
*/
/////////////////////////////////////////////////
/////////////////////////////////////////////////
#include <iostream>
#include <cstring>
using namespace std;
class A
{
public:
        A()
        {
                cout<<"construct"<<endl;
                strcpy(name,"zhangsan");
        }
        ~A()
        {
                cout<<"destruct"<<endl;
        }
        A(const A& temp)
        {
                cout<<"copy"<<endl;
                strcpy(name,temp.name);
        }
        A& operator= (const A& temp)
        {
            cout << "operator=" << endl;
            strcpy(name, temp.name);
            return *this;
        }
private:
        char name[16];
};
////////////////////////////
A f()
{
        cout<<"------------function f----------"<<endl;
        A b;
        return b;
}
////////////////////////////
int     main()
{
        A b;
        b = f();//A b(f());
        return 0;
}
/*
测试输出结果:
VS2005release模式//优化了
construct
------------function f----------
construct
operator=
destruct
destruct
*/
/*
vs2005Debug模式//未优化,跟书上的一致
construct
------------function f----------
construct
copy
destruct
operator=
destruct
destruct
*/

二、分析

  对于采用了NRV优化的编译器来说(例如:VS的release模式、G++),没有临时对象产生。但是对于debug模式下,会产生临时对象。

 Debug模式下做法是:局部对象-->临时对象-->外部对象。

 说明:第一个箭头调用拷贝构造函数产生了临时对象,第二个箭头调用operator=操作。

 Release模式下做法是:局部对象-->外部对象。

 说明:调用operator=操作

  从图1和图3可以看到,调用operator=操作都是在main()函数中进行,这就意味着operator=的右值必须是存在的对象。在debug模式下,临时对象的地址是在main()函数作用域中,这没有问题。在release模式下,“临时对象"和局部对象合并了。原因如下:局部对象是在函数f()中创建的,但是它的地址空间是main()函数的,从图3和图4可以看到创建局部对象时,使用的地址空间是在main()中申请的“临时对象”空间。这点跟上一篇文章分析的NRV优化类似,都是把临时对象的地址传递进函数f(),然后局部对象就在这个地址上创建,这样就减少了拷贝构造函数的调用。

   

三、OD调试截图

 图 1 debug模式main()函数

图 2 debug模式f()函数

 

图 3 release模式main()函数 

图 4 release模式f()函数

 

相关阅读 更多 +
排行榜 更多 +
方块拼凑最新版 v1.0 安卓版

方块拼凑最新版 v1.0 安卓版

休闲益智 下载
方块拼凑最新版 v1.0 安卓版

方块拼凑最新版 v1.0 安卓版

休闲益智 下载
愤怒的小鸟爆破安卓版 v2.7.0 手机版

愤怒的小鸟爆破安卓版 v2.7.0 手机版

飞行射击 下载