2012-11-14 32 views
13

可能重複:
Inline functions vs Preprocessor macros內聯函數VS宏功能

我想知道內聯函數和宏功能之間的差異。

1)內聯函數是否是一樣的宏函數?

2)我知道這兩個都沒有被調用,但是它們在編譯階段被它的代碼所取代。不是?

3)如果有差異,你能指定它嗎?

+0

http://msdn.microsoft.com/en-us/library/bf6bf4cf.aspx – CCoder

回答

22

內聯替換調用與函數體的功能,但是,內聯僅僅是一個要求到可忽略(你仍然可以通過一些標誌編譯器強制在線或使用編譯器帶gcc的always_inline屬性)。

另一方面,宏在編譯之前由預處理器進行了擴展,所以它就像文本替換,宏也不是類型檢查,內聯函數是。有一個比較wiki

爲了完整起見,你仍然可以有某種與宏類型安全的,使用gcc的__typeof__例如,如果用錯誤的類型用下面的產生幾乎相同的代碼,並互爲因果警告:

#define max(a,b) \ 
    ({ __typeof__ (a) _a = (a); \ 
     __typeof__ (b) _b = (b); \ 
    _a > _b ? _a : _b; }) 

__attribute__((always_inline)) int max(int a, int b) { 
    return (a > b ? a : b); 
} 

注意:有時無類型的宏只是需要的,例如,看看uthash如何使用宏來使任何C結構可以散列而不需要轉換。

1

inlinemacro的定義不同,因爲宏是預處理的,但是內聯只是編譯器將整個函數放在調用它的地方的指示。

把inline關鍵字任何函數定義之前僅僅是指示或要求,編譯器可以自由選擇是否將讓那個內聯函數或將其作爲正常

宏替換:preprocessing phase(即在編譯之前)

- 在linux輸入文件test.c結果文件test.i

直列取代:compilation phase

6

宏是由預處理器替換的聲明(在實際編譯前爲)根本不是函數。在實際的編譯階段開始之前宏已經很久了,剩下的就是它們的擴展(包括擴展到無)。

事實上,內聯函數符合語言規範函數,其中包含範圍規則,變量聲明,邏輯結構(循環等)等等。內聯函數不像宏那樣擴展預編譯步驟。它們是編譯就像常規代碼一樣,但可以注入(因缺少更好的術語)編譯後的代碼並根據需要進行優化。

+0

你仍然可以用宏{},聲明和循環宏 – iabdalkader

+0

@mux有人篡改預處理器語言(這是所有宏)是,而我沒有看?我還沒有看到在C/C++宏中定義的控制循環(因此在預處理之後被替代),但是我非常希望看到這樣的示例。在預處理解析階段,無論宏**發出什麼**,你都可以有'{...}'的範圍,但是如果有一種方法可以執行'#for i = 0'或'#while(true) '在預處理器宏中構造,我從來沒有見過它(但是,再次感興趣的是看到你的例子)。 – WhozCraig

+0

看看[uthash](http://www.codeforge.com/read/104731/uthash.h__html)哈希表(和鏈表)庫的源代碼完全用宏編寫:) – iabdalkader

17

1)號

2)在C A宏僅僅是一個膨脹編譯器之前處理的源代碼的文本。 inline關鍵字用於向編譯器提示該函數可以內聯放置,而不需要設置調用堆棧。

因此,舉例來說,可以說,你有代碼以下兩個片段(一宏,然後將內聯函數):

#define MAX(x,y)  (x > y ? x : y) 

inline int max(int x, int y) { return x > y ? x : y; } 

當預處理程序發現在您的代碼中的以下呼叫:

int highest = MAX (var_1, var_2); 

它將其替換爲

int highest = (var_1 > var_2 ? var_1 : var_2); 

上面的是什麼編譯器編譯過程最終獲得的,因此由MAX(X,Y)所限定的片段是替換爲MAX(VAR_1,VAR_2)。當編譯器發現功能調用

int highest = max (var_1, var_2); 

然後函數「max」被調用。你必須假設它被稱爲正常的方式,因爲編譯器可以自由地忽略你的「內聯」提示,並且調用函數通過正常的調用堆棧,而不是簡單地將函數的代碼放在它所在的位置遇到。

最後一個警告與宏:因爲它是所有文本替換,而不是代碼替換,如果你做這樣的事情:

int highest = MAX (v1++, v2++); 

預處理器將展開到:

int highest = (v1++ > v2++ ? v1++ : v2++); 

這可能不是你想要的。