返回值优化,是一种属于编译器的技术,它通过转换源代码和对象的创建来加快源代码的执行速度。RVO = return value optimization。

测试平台:STM32F103VG + Keil 5.15

背景:
我们有个MacAddress::ToArray

byte* MacAddress::ToArray() const
{
return (byte*)&Value;
}

因为封装需要,打算返回字节数组类ByteArray的对象,于是有

ByteArray MacAddress::ToArray() const
{
return ByteArray((byte*)&Value, );
}

调用代码

ByteArray bs = mac.ToArray();
bs.CopyTo(General_reg.SHAR);

按照我浅薄的C++知识理解,在ToArray内return 的时候,会产生一次对象拷贝,到临时对象。
然后在调用者那里的等号,产生一次拷贝构造。

实际上,编译烧写调试,查看反汇编

   :         ByteArray bs = mac.ToArray();
0x0800595C MOV r1,r5
0x0800595E A804 ADD r0,sp,#0x10
0x08005960 F000FE92 BL.W MacAddress::ToArray (0x08006688)
: bs.CopyTo(General_reg.SHAR);
:
0x08005964 MOVS r3,#0x00
0x08005966 461A MOV r2,r3
0x08005968 F1040109 ADD r1,r4,#0x09
0x0800596C A804 ADD r0,sp,#0x10
0x0800596E F002FB8F BL.W Array::CopyTo (0x08008090)

直接分配内存,传入ToArray使用。ToArray之后,并没有见到所猜想的第二次拷贝构造。
下面看看ToArray的反汇编

0x08006688 B570      PUSH     {r4-r6,lr}
0x0800668A MOV r5,r0
0x0800668C 460C MOV r4,r1
: return ByteArray((byte*)&Value, );
0x0800668E MOVS r2,#0x06
0x08006690 F1040108 ADD r1,r4,#0x08
0x08006694 MOV r0,r5
0x08006696 F7FFFDEB BL.W _ZN9ByteArrayC2EPKhi (0x08006270)
0x0800669A MOV r5,r0
: }
0x0800669C BD70 POP {r4-r6,pc}

天哪!这里面只有一次构造函数,并不是猜想的那样,先构造本地变量,然后return再拷贝。
并且,这个构造函数的内存地址,正是外部传进去的那一个。

这个就是C++的RVO,返回值优化技术,没想到MDK也支持。

这个技能的获取,让我C++水平从30%提升到40%

C++返回值优化RVO的更多相关文章

  1. 返回值优化 RVO

    <深度探索C++对象模型>-- 2.3 返回值的初始化 & 在编译器层面做优化

  2. 【M20】协助完成“返回值优化(RVO)”

    1.方法返回对象,会导致临时对象的产生,这降低了效率,const Rational operator* (const Rational& lhs,Rational& rhs).有没有什 ...

  3. 返回值优化(RVO)

    C++的函数中,如果返回值是一个对象,那么理论上它不可避免的会调用对象的构造函数和析构函数,从而导致一定的效率损耗.如下函数所示: A test() { A a; return a; } 在test函 ...

  4. 一段小代码秒懂C++右值引用和RVO(返回值优化)的误区

    关于C++右值引用的参考文档里面有明确提到,右值引用可以延长临时变量的周期.如: std::string&& r3 = s1 + s1; // okay: rvalue referen ...

  5. [转] C++中临时对象及返回值优化

    http://www.cnblogs.com/xkfz007/articles/2506022.html 什么是临时对象? C++真正的临时对象是不可见的匿名对象,不会出现在你的源码中,但是程序在运行 ...

  6. [More Effective C++]条款22有关返回值优化的验证结果

    (这里的验证结果是针对返回值优化的,其实和条款22本身所说的,考虑以操作符复合形式(op=)取代其独身形式(op),关系不大.书生注) 在[More Effective C++]条款22的最后,在返回 ...

  7. 转:C++中临时对象及返回值优化

    http://www.cnblogs.com/xkfz007/articles/2506022.html 什么是临时对象? C++真正的临时对象是不可见的匿名对象,不会出现在你的源码中,但是程序在运行 ...

  8. C++返回值优化

    返回值优化(Return Value Optimization,简称RVO)是一种编译器优化机制:当函数需要返回一个对象的时候,如果自己创建一个临时对象用于返回,那么这个临时对象会消耗一个构造函数(C ...

  9. C++标准库之string返回值研究

    先说结论(不一定适用所有环境): 1) GCC默认开启了返回值优化(RVO),除非编译时指定“-fno-elide-constructors”: 2) 现代C++编译器一般都支持返回值优化: 3) s ...

随机推荐

  1. JAVA入门[10]-mybatis分页查询

    1.添加分页插件 在mybatis-generator-config.xml添加plugin节点: <plugin type="org.mybatis.generator.plugin ...

  2. Hibernate(或其它ORM)里的inverse用法详解,内容摘自Java web轻量级开发面试教程

    本文来是从 java web轻量级开发面试教程从摘录的. Inverse的英文含义是反转,在Hibernate中用来决定是由哪方来维护两个业务实体类之间的关联关系,具体而言,就是由哪方去设置这个被外键 ...

  3. 自学Zabbix3.8.2-可视化Visualisation-maps网络地图

    自学Zabbix3.8.2-可视化Visualisation-maps网络地图 可以简单的理解为动态网络拓扑图,可以针对业务来配置zabbix map,通过map可以了解应用的整体状况:服务器是否异常 ...

  4. Material使用07 MatGridListModule的使用

    1 MatGridListModule简介 对相似数据的展现,尤其是像是图片的展示 使用起来很像表格 官方文档:点击前往 2 MatGridListModule提供的指令 2.1 mat-grid-l ...

  5. IntelliJ IDEA 设置Output (输出窗口)窗口字体大小

    Settings-->Editor-->Colors&Fonts-->Console Font 如图: 字体调好了以后使用起来眼睛就轻松多了

  6. 为eclipse离线安装hibernate tools插件

    工具/原料   eclipse luna jboss hibernate tools 方法/步骤     下载hibernate tools插件   在eclipse根目录下创建myplugins和l ...

  7. SVN 安装与使用教程总结

    转载:http://www.cnblogs.com/armyfai/p/3985660.html SVN简介: 为什么要使用SVN? 程序员在编写程序的过程中,每个程序员都会生成很多不同的版本,这就需 ...

  8. Hue上的Oozie构建工作流和定时任务步骤

    Oozie是什么? Oozie是一种Java Web应用程序,它运行在Java servlet容器--即Tomcat--中,并使用数据库来存储以下内容: 工作流定义 当前运行的工作流实例,包括实例的状 ...

  9. Angular 非父子组件间的service数据通信

    完成思路:以service.ts(主题subject---订阅sbuscribe模式)为数据中转中间件,通过sku.ts的数据更改监测机制,同步更改service.ts中的数据,同时buy.ts组件实 ...

  10. 如何优雅地在React项目中使用Redux

    前言 或许你当前的项目还没有到应用Redux的程度,但提前了解一下也没有坏处,本文不会安利大家使用Redux 概念 首先我们会用到哪些框架和工具呢? React UI框架 Redux 状态管理工具,与 ...