關於行內函數寫法的總結體會
關於行內函數寫法的總結體會
1.行內函數的作用
在編譯階段,在呼叫處,將行內函數展開,展開這一點類似於巨集。相應的優點則是節省了函式呼叫的開銷。inline適合修飾函式體短小的,因為這樣節省下來開銷的優點才不至於被程式碼量過大而掩蓋。
2.行內函數的基本使用方法
只需要給函式加上inline修飾即可。比如:
inline char fun (int a, int b);
inline void fun1(int a , int b)
{
return;
}
但是使用pclint靜態檢查的時候,我們會發現,所有使用inline函式的地方都會有個一warning資訊,建議在inline前使用static修飾。所以這裡主要討論一下static和inline配合使用以及行內函數的宣告和定義到底應該怎麼寫的問題。
討論之前先指明實現內聯展開的基本原則:
- 在編譯期間,某個.o內部可以找到該行內函數的定義,而不是隻有一個宣告
- 每個.o尋找行內函數定義的範圍僅限於該.c檔案和它include的標頭檔案內
按照以下幾種函式宣告、定義、呼叫情況討論:
A. 普通函式的最常見寫法—函式fun,宣告在a.h、定義在a.c
1)沒有使用static修飾的情況下,任何其他.c呼叫這個行內函數,均無法展開,只會把它當作一個普通的函式來呼叫。原因很簡單,因為其他.c在編譯期間看不到這個行內函數的定義,定義只在a.c中。
2)使用static修飾的情況下,static修飾函式的主要作用是把函式宣告為私有,a.c如果要使用fun沒有問題,但是其他.c就會出現找不到定義的問題,所以這種寫法根本就不可行。
3)如果繼續使用static修飾,為了解決找不到定義的問題,則需要在所有呼叫fun的.c中都新增一份static修飾的fun定義。這樣的話,每個.c在編譯的時候都能找到函式的定義,既解決了2)中的找不到定義的問題,又解決了1)中的內聯無法展開的問題。這種方法可以真正實現內聯展開。
B.函式fun,直接在a.h寫函式的定義
1)沒有使用static修飾的情況下,b.c/c.c等多個C檔案都include了a.h,會報函式的重定義錯誤,連線會失敗,所以這種寫法也是不可行的。
2)使用static修飾,由於宣告成私有,所以其他.c都有一份fun的定義也沒有問題,這種寫法是可行的,也是最推薦的。
綜上所述,只有A/3) 和 B/2)兩種方法是可以發揮行內函數的效用的,而且兩中都是有static修飾的,這也就是為什麼pclint會推薦增加static修飾,想要發揮效果一定是需要static的。就算只有一個.c自己定義自己呼叫,新增static宣告為私有也是合理的。而且兩種方法相比,顯然B/2)更簡潔。因為A/3)程式碼量會增大,而且後期每新增一個.c都需要增加一份該函式的定義,顯然不合適。所以最合適的方法就是B/2)。