| 特性 | 內聯函數 | 宏定義 |
|---|---|---|
| 型別檢查 | ✅ 編譯器執行完整型別檢查/自動轉換 | ❌ 純文字替換,無型別檢查 |
| 除錯支援 | ✅ 可設中斷點、單步追蹤 | ❌ 預處理階段展開,無法除錯 |
| 類別成員存取 | ✅ 可存取 private/protected 成員 | ❌ 無 this 指標,無法存取 |
| 參數副作用 | ✅ 參數僅求值一次 | ❌ 多次展開導致多次求值(如 MAX(i++,j)) |
| 優先級陷阱 | ✅ 無運算子優先級問題 | ❌ 需手動加括號包裹整個表達式與每個參數 |
| 編譯階段 | 編譯期(符號表保留函數體) | 預處理期(純文字替換) |
#define MAX(a,b) ((a)>(b)?(a):(b))
int i=1, j=0;
MAX(i++, j); // i 增加 2 次!展開為 ((i++)>(j)?(i++):(j))
MAX(i++, j+10); // i 增加 1 次
MAX(5, "hello"); // 編譯通過但邏輯錯誤,比較 int 與字串指標
inline int Max(int a, int b) {
return a > b ? a : b;
}
// 類別內定義自動視為內聯
class A {
void foo() { cout << "inline\n"; } // 隱式 inline
};
inline 只是建議,編譯器有最終決定權。唯一常見例外:assert 斷言宏。因為斷言僅在 Debug 版生效,若為函數會因呼叫開銷導致 Debug/Release 行為差異(記憶體佈局、時序改變),宏能確保零開銷且不影響 Release 版程式碼。
inline / constexpr 函數 替代所有宏。constexpr if、if constexpr 替代條件編譯宏。內聯函數兼具宏的效率與函數的型別安全,是現代 C++ 取代宏的標準工具。除極少數預處理元程式場景外,應全面遷移至 inline/constexpr。