變參(不定參)的巨集函式
1.可變的巨集是具有不定引數的巨集。這些引數用...代表,被儲存到__VA_ARGS__中。他會在內部進行擴充套件。
#defien err(...) fprintf(stderr, __AV_ARGS__)err("%s file total %dMB.\n", "hello.c", 2) ;
預處理後為: fprintf(stderr, %s file total %dMB.\n", "hello.c",2) ;
2.可變的巨集可以包含命名引數(在...之前)如:
#define errout(a, b, ...) fprintf(stderr, "file %s |%d|\n",a,b); fprintf(stderr,__VA_ARGS__)
3.很多時候我們在呼叫程式出錯時都需要輸出帶file帶line的log。我們可能會這樣寫
if(err) fputs(stderr, %s file:|%d|: %s\n", __FILE__, __LINE__, error message) ;
但是我們發現輸出錯誤所在的檔案和行時都要寫這兩個巨集變數很麻煩。我們需要的時自動把file和line加到錯誤資訊中。那麼我們用不定引數巨集加一些小技巧搞定。
#define errout(...) _errout(__FILE__, __LINE__, __VA_ARGS__)
#define _errout(file, line, ...) fprintf(stderr, "File %s:|%d| \n", file, line) ;\
fprintf(stderr, __VA_ARGS__)
這樣只需寫入錯誤資訊,file和line就會“自動”輸出出來。
注意1 fmt... 必須帶...要不然就不能給dbg傳遞不定引數, 編譯器會認為巨集dbg()是定引數的,
//2dbg()的定義不能帶... 原因很簡單你會在printf()最後加...嗎?
#define dbg(log_level, fmt...) kickstart(log_level, _FUNCTION, _LINE, fmt)
void
kickstart(int log_level, const char *func_name, int line_number, const char *format, ...)
{
;
}
dbg(x, y, z, q, 1, 3 ,4) ;
說明:
對編譯器有要求,c99支援,g++不支援,
參考文章:http://www.jeffhung.net/blog/articles/jeffhung/1013/