[c++] 內聯函數vs預處理器宏



Answers

首先,編譯前的預處理宏只是代碼中的“複製粘貼”。 所以沒有類型檢查 ,並且可能出現一些副作用

例如,如果你想比較2個值:

#define max(a,b) ((a<b)?b:a)

例如,如果使用max(a++,b++) ,則會出現副作用( ab會增加兩次)。 相反,使用(例如)

inline int max( int a, int b) { return ((a<b)?b:a); }
Question

內聯函數與預處理器宏有什麼不同?




如果內聯函數中存在任何迭代或遞歸語句,內聯函數將表現為函數調用,以防止重複執行指令。 它對保存程序的整體內存非常有幫助。




內聯函數將保持值語義,而預處理器宏只是複制語法。 如果多次使用參數,可以使用預處理器宏獲得非常微妙的錯誤 - 例如,如果參數包含像“i ++”這樣的具有執行兩次的突變,這是相當令人驚訝的。 內聯函數不會有這個問題。




宏忽略名稱空間。 這使他們變得邪惡。




在海灣合作委員會(我不確定其他人),聲明一個函數內聯,只是一個暗示編譯器。 編譯器在一天結束時仍然要決定是否在函數被調用時包含函數的主體。

內聯函數和預處理器宏之間的差異相對較大。 預處理器宏在一天結束時只是文本替換。 您放棄了編譯器執行檢查參數和返回類型類型檢查的許多功能。 對參數的評估是非常不同的(如果你傳遞給函數的表達式有副作用,那麼調試時你會覺得很有趣)。 關於函數和宏的使用位置有細微的差別。 例如,如果我有:

#define MACRO_FUNC(X) ...

MACRO_FUNC顯然定義了函數的主體。 需要特別小心,以便在任何情況下都可以正常運行功能,例如寫得不好的MACRO_FUNC會導致錯誤

if(MACRO_FUNC(y)) {
 ...body
}

一個正常的功能可以用在那裡沒有問題。




關鍵的區別是類型檢查。 編譯器將檢查你作為輸入值傳遞的是可以傳遞給函數的類型。 預處理器宏並非如此 - 它們在任何類型檢查之前都會擴展,並且可能導致嚴重且難以檢測到的錯誤。

Here是其他幾個不太明顯的要點。




Links