LINUX C中如何定義可變引數的巨集
阿新 • • 發佈:2019-01-25
轉載:http://darksun.blog.51cto.com/3874064/1379569
一般在除錯列印Debug資訊的時候, 需要可變引數的巨集. 從C99開始可以使編譯器標準支援可變引數巨集(variadic macros), 另外GCC也支援可變引數巨集, 但是兩種在細節上可能存在區別.
1. __VA_ARGS__
__VA_ARGS__ 將 "..." 傳遞給巨集 . 如
#define debug1(...) fprintf(stderr, __VA_ARGS__) #define debug2(format, ...) fprintf(stderr, format, __VA_ARGS__)
2. GCC的複雜巨集
#define debug1(args...) fprintf(stderr, args)
#define debug2(format, args...) fprintf(stderr, format, args)
這和第一條的巨集例子是完全一樣的,但是這麼寫可讀性更強並且更容易進行描述.3. ##__VA_ARGS__, ##args
上面兩個定義的巨集,如果出現 debug2("A Message")的時候,由於巨集展開後有個多餘的逗號,所以將導致編譯錯誤.
為了解決這個問題,CPP 使用一個特殊的"##"操作,格式如下:
#define debug3(format, ...) fprintf(stderr, format, ##__VA_ARGS__)
#define debug3(format, args...) fprintf(stderr, format, ##args)
這裡,如果可變引數被忽略或為空,"##"操作將使前處理器(preprocessor)去除掉它前面的那個逗號.舉例:
debug1("t1"); // print "t1" debug2("t2"); // compile error(gcc but vs) debug2("t%d", 2); // print "t2" debug3("t3"); // print "t3" debug3("t%d", 3); // print "t3"