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

這裏,"…"指可變參數。這類宏在被調用時,它(這裏指"…”)被表示成零個或多個符號,包括裏面的逗號,始終到到右括弧告終為止。