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%
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
我不相信神话,我只相信汗水!我不相信命运,我只相信双手!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
2011-09-01 XCode中如何使用事务