1. C99中新添加了可變參數宏
1 #define dgbmsg(fmt,...) /
2 printf(fmt,__VA_ARGS__)
__VA_ARGS__ 將"..." 傳遞給宏
2. GCC 的複雜宏
GCC使用一種不同的語法從而可以使你可以給可變參數一個名字,如同其它參數一樣。
#define debug(format, args...) fprintf (stderr, format, args)
這和上面舉的那個定義的宏例子是完全一樣的,但是這麼寫可讀性更強並且更容易進行描述。
3. ##__VA_ARGS__
上面兩個定義的宏, 如果出現debug("A Message") 的時候, 由於宏展開後有個多餘的逗號, 所以將導致編譯錯誤. 為了解決這個問題,CPP使用一個特殊的‘##’操作。
#define debug(format, ...) fprintf (stderr, format, ## __VA_ARGS__)
這裏,如果可變參數被忽略或為空,‘##’操作將使預處理器(preprocessor)去除掉它前面的那個逗號。如果你在宏調用時,確實提供了一些可變參數,GNU CPP也會工作正常,它會把這些可變參數放到逗號的後面。
4. 其他方法
一種流行的技巧是用一個單獨的用括弧括起來的的 "參數" 定義和調用宏, 參數在宏擴展的時候成為類似 printf() 那樣的函數的整個參數列表。
#define DEBUG(args) (printf("DEBUG: "), printf(args))
藉助宏可以在程序正式發佈的時候節省很多資源:
1 #define DEBUGMODE
2 #ifdef DEBUGMODE
3 #define MSG(fmt, a...) \
4 printf("%s,%s(),%d:" fmt "/n", __FILE__,__FUNCTION__,__LINE__, ##a)
5 #else
6 #define MSG(fmt, a...)
7 #endif
這裏,"…"指可變參數。這類宏在被調用時,它(這裏指"…”)被表示成零個或多個符號,包括裏面的逗號,始終到到右括弧告終為止。