11.22 怎樣寫參數個數可變的宏?

一種流行的技巧是用一個單獨的用括弧括起來的的 ``參數" 定義和調用宏, 參數在 宏擴展的時候成為類似 printf() 那樣的函數的整個參數列表。
    #define DEBUG(args) (printf("DEBUG: "), printf args)

    if(n != 0) DEBUG(("n is %d\n", n));

明顯的缺陷是調用者必須記住使用一對額外的括弧。

gcc 有一個擴展可以讓函數式的宏接受可變個數的參數。 但這不是標準。另一種 可能的解決方案是根據參數個數使用多個宏 (DEBUG1, DEBUG2, 等等), 或者用 逗號玩個這樣的花招:

    #define DEBUG(args) (printf("DEBUG: "), printf(args))
    #define _ ,

    DEBUG("i = %d" _ i);

C99 引入了對參數個數可變的函數式宏的正式支持。在宏 ``原型" 的末尾加上符號 ... (就像在參數可變的函數定義中), 宏定義中的偽宏 __VA_ARGS__ 就會在調用是 替換成可變參數。

最後, 你總是可以使用真實的函數, 接受明確定義的可變參數。 參見問題 15.4 和 15.5。如果你需要替換宏, 使用一個 函數和一個非函數式宏, 如 #define printf myprintf。

參考資料: [C9X, Sec. 6.8.3, Sec. 6.8.3.1]。

翻譯朱群英、孫雲, LaTeX2HTML 編譯 朱群英 (2005-06-23)