inline函式 第6課 內聯函式分析

2021-10-11 10:33:29 字數 1907 閱讀 4720

一、 常量與巨集回顧

c++中的const常量可以替代巨集常數定義,如:

const int a = 3;等價於 #define a 3

那麼c++中是否有解決方案替代巨集**片段呢?請看以下內容。

二、 內聯函式的定義

(1)c++中推薦使用內聯函式替代巨集**片段;

(2)c++中使用inline關鍵字宣告內聯函式;

(3)內聯函式宣告時inline關鍵字必須和函式定義結合再一起,否則編譯器會直接忽略內聯請求。內聯函式的定義如圖1所示:

三、 內聯函式的特點

(1)c++編譯器可以將乙個函式進行內聯編譯,被c++編譯器內聯編譯的函式叫做內聯函式;

(2)c++編譯器直接將函式體插入函式呼叫的地方;

(3)內聯函式沒有普通函式呼叫時的額外開銷(壓棧,跳轉,返回);

(4)c++編譯器不一定滿足函式的內聯請求;函式的內聯請求可能被編譯器拒絕;

(5)內聯函式具有普通函式的特徵(引數檢查,返回型別等 );

(6)巨集**片段由預處理器處理,進行簡單的文字替換 ,沒有任何編譯過程,因此可能出現***。

如圖2所示的**,用情況1編譯後的執行結果如圖3所示;這就是巨集**出現的***,情況1的文字替換後如圖 4所示:

用圖2**的情況2編譯執行後的結果如圖5所示,這個就和分析的一樣,因此內聯函式不會產生***。

用圖2**的情況2在vs2015的預設編譯後的彙編**如圖6所示;從圖6中可以看到有函式的呼叫,說明inline的內聯請求被拒絕了;這是因為編譯器的優化功能沒有被設定。編譯器的優化功能設定如圖7所示,經過設定了編譯器的優化功能後,編譯後的彙編**如圖8所示,從圖8中可以到沒有函式呼叫了,而是將函式體插入函式呼叫的地方。

四、 現代c++編譯器對內聯函式的優化

(1)現代c++編譯器能夠進行編譯優化 ,一些函式即使沒有inline宣告,也可能被內聯編譯。

(2)一些現代c++編譯器提供了擴充套件語法,能夠對函式進行強制內聯,如圖9的**和如下所示:

a) g++:__attribute__((always_inline))屬性

五、 c++中inline內聯編譯的限制

(1)不能存在任何形式的迴圈語句;

(2)不能存在過多的條件判斷 語句;

(3)函式體不能過於龐大;

(4)不能對函式進行取位址操作;

(5)函式內聯宣告必須在呼叫語句之前。

六、 內聯函式、巨集和帶引數函式三者的比較

內聯函式的優點:函式**被裝入符號表中,在使用時進行替換沒有呼叫開銷,效率高,會進行引數型別檢查。

內聯函式的缺點:函式**較長,使用內聯將消耗過多記憶體;

函式體內有迴圈,執行**的時間比較長。

巨集的優點:原地展開,沒有呼叫開銷;

並且在預處理階段完成,不占用編譯時間。

巨集的缺點:不進行型別檢查,多次巨集替換會導致**體積變大;

一些引數的***會導致得出錯誤的結果。

帶參函式的優點:編譯器會做引數的靜態型別檢查。

帶參函式的缺點:需要傳參、棧變數的開闢和銷毀;

壓棧、跳轉、返回開銷;

第6課 內聯函式分析

帶參函式巨集內聯函式 優點編譯器會做引數的靜態型別檢查 原地展開,沒有呼叫開銷 並且在預處理階段完成,不占用編譯時間。函式 被裝入符號表中,在使用時進行替換 沒有呼叫開銷,效率高,會進行引數型別檢查 缺點需要傳參 棧變數的開闢和銷毀 壓棧 跳轉 返回開銷 不進行型別檢查,多次巨集替換會導致 體積變大...

C 第6課 內聯函式分析

本文學習自 狄泰軟體學院 唐佐林老師的 c 課程 引入 c 內聯函式的引入是為了替換c中巨集 塊功能 實驗1 巨集 塊 vs 內聯函式 注意 在c 開發中首選內聯函式定義 塊,而不是巨集實驗2 強制內聯 c語言中的巨集常量只是在預處理期間進行鍵的文字替換,它的 是並不會進行任何的語法檢查,型別檢查。...

inline函式 C 內聯函式 inline

inline要起作用,必須要與函式定義放在一起,而不是函式的宣告 inline 當編譯器處理呼叫內聯函式的語句時,不會將該語句編譯成函式呼叫的指令,而是直接將整個函式體的 插人呼叫語句處,就像整個函式體在呼叫處被重寫了一遍一樣,在執行時是順序執行,而不會進行跳轉。優點 內聯函式沒有執行函式呼叫的開銷...