zoukankan      html  css  js  c++  java
  • 编译器对临时变量的优化简单理解

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

    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()函数

  • 相关阅读:
    04.DRF-开发REST 接口
    03.DRF-设计方法
    02.DRF-认识RESTful
    01.DRF-Web应用模式
    14.Django-xadmin和富文本编辑器
    13.Django-分页
    12.Django-admin
    11.Django-form表单上传文件
    android 基于wifi模块通信开发
    android蓝牙通讯开发(详细)
  • 原文地址:https://www.cnblogs.com/cswuyg/p/1805049.html
Copyright © 2011-2022 走看看