為什么不建議函數有太多參數?


記錄一篇今天工作的思考。為什么不建議函數的有太多參數?


今天做組內代碼評審時,發現同事的代碼有一個小問題,一個函數添加了一個參數后有了7個參數,而公司的編碼規范要求,函數的參數不許超過6個。

后來我就研究了一下,為啥不建議函數有太多參數呢?當然函數參數太多,不利於維護,學習成本比較高。除此之外,函數參數太多對性能也有一定的影響。


觀察參數傳遞方式

我做了一個實驗,觀察對含有6個、7個、8個參數的函數進行調用時,到底有哪些不同,測試代碼如下:

#include <iostream>

void func6(int p1, int p2, int p3, int p4, int p5,
           int p6)
{
}

void func7(int p1, int p2, int p3, int p4, int p5,
           int p6, int p7)
{
}

void func8(int p1, int p2, int p3, int p4, int p5,
           int p6, int p7, int p8)
{
}

int main()
{
    func6(1, 2, 3, 4, 5, 6);
    func7(1, 2, 3, 4, 5, 6, 7);
    func8(1, 2, 3, 4, 5, 6, 7, 8);
    return 0;
}

我們查看匯編代碼,來觀察調用時如何傳遞參數。

我們看一下func6的調用,全部通過寄存器傳遞。

   0x00005555555551ce <+8>:     mov    r9d,0x6
   0x00005555555551d4 <+14>:    mov    r8d,0x5
   0x00005555555551da <+20>:    mov    ecx,0x4
   0x00005555555551df <+25>:    mov    edx,0x3
   0x00005555555551e4 <+30>:    mov    esi,0x2
   0x00005555555551e9 <+35>:    mov    edi,0x1
   0x00005555555551ee <+40>:    call   0x555555555169 <func6(int, int, int, int, int, int)>

我們看一下func7的調用,參數1~6通過寄存器,參數7通過堆棧傳遞。


   0x00005555555551f3 <+45>:    push   0x7
   0x00005555555551f5 <+47>:    mov    r9d,0x6
   0x00005555555551fb <+53>:    mov    r8d,0x5
   0x0000555555555201 <+59>:    mov    ecx,0x4
   0x0000555555555206 <+64>:    mov    edx,0x3
   0x000055555555520b <+69>:    mov    esi,0x2
   0x0000555555555210 <+74>:    mov    edi,0x1
   0x0000555555555215 <+79>:    call   0x555555555188 <func7(int, int, int, int, int, int, int)>

我們看一下func8的調用,參數16通過寄存器,參數78通過堆棧傳遞。

   0x000055555555521e <+88>:    push   0x8
   0x0000555555555220 <+90>:    push   0x7
   0x0000555555555222 <+92>:    mov    r9d,0x6
   0x0000555555555228 <+98>:    mov    r8d,0x5
   0x000055555555522e <+104>:   mov    ecx,0x4
   0x0000555555555233 <+109>:   mov    edx,0x3
   0x0000555555555238 <+114>:   mov    esi,0x2
   0x000055555555523d <+119>:   mov    edi,0x1
   0x0000555555555242 <+124>:   call   0x5555555551a7 <func8(int, int, int, int, int, int, int, int)>

結論

gcc編譯器(gcc9),在x64環境下。函數調用時,前6個參數通過寄存器傳遞,超過6個后面的參數通過堆棧傳遞。而寄存器傳遞參數比堆棧傳遞效率高,所以建議函數參數不要超過6個。

學習c++還是要學習一些匯編的,可以解決很多問題啊。


最后,東北碼農,全網同名,求關注、點贊、轉發,謝謝~


免責聲明!

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



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