記錄一篇今天工作的思考。為什么不建議函數的有太多參數?
今天做組內代碼評審時,發現同事的代碼有一個小問題,一個函數添加了一個參數后有了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++還是要學習一些匯編的,可以解決很多問題啊。
最后,東北碼農,全網同名,求關注、點贊、轉發,謝謝~
