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%

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM