5 行內函數
阿新 • • 發佈:2020-09-19
目錄
1 常量與巨集回顧
-
C++ 中的
const
常量可以替代巨集常數定義,如:const int A = 3; <=> #define A 3
-
問題:C++ 中是否有解決方案替代巨集程式碼片段?
2 行內函數
-
C++ 中推薦使用行內函數替代巨集程式碼片段
-
C++ 中使用
inline
關鍵字宣告行內函數行內函數宣告時
inline
關鍵字必須和函式定義結合在一起,否則編譯器會直接忽略內聯請求inline int func(int a,int b) { return a < b ? a : b; }
-
C++ 編譯器可以將一個函式進行內聯編譯
-
被 C++ 編譯器內聯編譯的函式叫做行內函數
-
C++ 編譯器直接將函式體插入函式呼叫的地方
-
行內函數沒有普通函式呼叫時的額外開銷(壓棧,跳轉,返回)
-
C++ 編譯器不一定滿足函式的內聯請求
-
行內函數示例1
-
Demo
#include <stdio.h> //巨集程式碼塊 #define FUNC(a, b) ((a) < (b) ? (a) : (b)) //行內函數塊 inline int func(int a, int b) { return a < b ? a : b; } int main(int argc, char *argv[]) { int a1 = 1, a2 = 1; int b1 = 3, b2 = 3; int c1 = FUNC(++a1, b1); //<=>int c = ((++a) < (b) ? (++a) : (b)) int c2 = func(++a2, b2); printf("a1 = %d\n", a1); //3 printf("b1 = %d\n", b1); //3 printf("c1 = %d\n", c1); //3 printf("a2 = %d\n", a2); //2 printf("b2 = %d\n", b2); //3 printf("c2 = %d\n", c2); //2 return 0; }
-
-
行內函數具有普通函式的特徵(引數檢查,返回型別等)
-
函式的內聯請求可能被編譯器拒絕
-
函式被內聯編譯後,函式體直接擴充套件到呼叫的地方
-
巨集程式碼片段由前處理器處理,進行簡單的文字替換,沒有任何編譯過程,因此可能出現副作用
-
現代 C++ 編譯器能夠進行編譯優化,一些函式即使沒有
inline
宣告,也可能被內聯編譯 -
一些現代 C++ 編譯器提供了擴充套件語法,能夠對函式進行強制內聯,如:
//g++ __attribute__((always_inline))屬性 //MSVC __forceinline
-
行內函數示例2
-
Demo
#include <stdio.h> //__forceinline //__attribute__((always_inline)) //inline int add_inline(int n); int main(int argc, char *argv[]) { int r = add_inline(10); printf(" r = %d\n", r); return 0; } inline int add_inline(int n) { int ret = 0; for(int i=0; i<n; i++) { ret += i; } return ret; }
-
3 注意事項
- C++ 中
inline
內聯編譯的限制- 不能存在任何形式的迴圈語句
- 不能存在過多的條件判斷語句
- 函式體不能過於龐大
- 不能對函式進行取址操作
- 函式內聯宣告必須在呼叫語句之前