C++返回值优化RVO

返回值优化,是一种属于编译器的技术,它通过转换源代码和对象的创建来加快源代码的执行速度。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, 6);
}

调用代码

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

按照我浅薄的C++知识理解,在ToArray内return 的时候,会产生一次对象拷贝,到临时对象。 然后在调用者那里的等号,产生一次拷贝构造。 实际上,编译烧写调试,查看反汇编

   358:         ByteArray bs = mac.ToArray(); 
0x0800595C 4629      MOV      r1,r5
0x0800595E A804      ADD      r0,sp,#0x10
0x08005960 F000FE92  BL.W     MacAddress::ToArray (0x08006688)
   359:         bs.CopyTo(General_reg.SHAR); 
   360:  
0x08005964 2300      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 4605      MOV      r5,r0
0x0800668C 460C      MOV      r4,r1
   481:         return ByteArray((byte*)&Value, 6); 
0x0800668E 2206      MOVS     r2,#0x06
0x08006690 F1040108  ADD      r1,r4,#0x08
0x08006694 4628      MOV      r0,r5
0x08006696 F7FFFDEB  BL.W     _ZN9ByteArrayC2EPKhi (0x08006270)
0x0800669A 4605      MOV      r5,r0
   482: } 
0x0800669C BD70      POP      {r4-r6,pc}

天哪!这里面只有一次构造函数,并不是猜想的那样,先构造本地变量,然后return再拷贝。 并且,这个构造函数的内存地址,正是外部传进去的那一个。 这个就是C++的RVO,返回值优化技术,没想到MDK也支持。 这个技能的获取,让我C++水平从30%提升到40%

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏张善友的专栏

如何结合IbatisNet的LIST遍历实现模糊查询

我仿照Java的Spring+Ibatis+Struct用Castle+IBatisNet+Asp.net的开发框架的DAO的基类:BaseSqlMapDao内...

25890
来自专栏前端新视界

由移动端级联选择器所引发的对于数据结构的思考

GitHub:https://github.com/nzbin/Framework7-CityPicker Demo:https://nzbin.githu...

44080
来自专栏码匠的流水账

聊聊kafka 0.8 ConsumerFetcherManager的MaxLag指标

本文主要研究一下kafka0.8.2.2版本中ConsumerFetcherManager的MaxLag指标的统计。

13110
来自专栏小樱的经验随笔

Codeforces 768B Code For 1

B. Code For 1 time limit per test:2 seconds memory limit per test:256 megabytes ...

40880
来自专栏码匠的流水账

聊聊storm的LoggingMetricsConsumer

storm-2.0.0/storm-client/src/jvm/org/apache/storm/metric/LoggingMetricsConsumer....

11630
来自专栏xingoo, 一个梦想做发明家的程序员

【设计模式】—— 备忘录模式Memento

  模式意图   这个模式主要是想通过一个对象来记录对象的某种状态,这样有利于在其他需要的场合进行恢复。   该模式还有跟多可以扩展的地方,比如可以记录多个时...

21550
来自专栏码匠的流水账

聊聊flink的RichParallelSourceFunction

flink-streaming-java_2.11-1.6.2-sources.jar!/org/apache/flink/streaming/api/func...

36410
来自专栏码匠的流水账

聊聊flink的RichParallelSourceFunction

flink-streaming-java_2.11-1.6.2-sources.jar!/org/apache/flink/streaming/api/func...

18720
来自专栏曾大稳的博客

Android ClassLoader流程解读并简单方式实现热更新

ClassLoader在启动Activity的时候会调用loadClass方法,我们就从这里入手:

32920
来自专栏Android知识点总结

看得见的数据结构Android版之双链表篇

8610

扫码关注云+社区

领取腾讯云代金券