變元論證巨集
Version >= C99
具有可變引數的巨集:
假設你要建立一些用於除錯程式碼的 print-macro,我們以此巨集為例:
#define debug_print(msg) printf("%s:%d %s", __FILE__, __LINE__, msg)
一些使用示例:
函式 somefunc()
如果失敗則返回 -1,如果成功則返回 0,並且從程式碼中的許多不同位置呼叫它:
int retVal = somefunc();
if(retVal == -1)
{
debug_printf("somefunc() has failed");
}
/* some other code */
retVal = somefunc();
if(retVal == -1)
{
debug_printf("somefunc() has failed");
}
如果 somefunc()
的實現發生變化會發生什麼,現在它會返回與不同可能的錯誤型別匹配的不同值?你仍然希望使用除錯巨集並列印錯誤值。
debug_printf(retVal); /* this would obviously fail */
debug_printf("%d",retVal); /* this would also fail */
為了解決這個問題,引入了 __VA_ARGS__
巨集。這個巨集允許多個引數 X-macro:
例:
#define debug_print(msg, ...) printf(msg, __VA_ARGS__) \
printf("\nError occurred in file:line (%s:%d)\n", __FILE__, __LINE)
用法:
int retVal = somefunc();
debug_print("retVal of somefunc() is-> %d", retVal);
此巨集允許你傳遞多個引數並列印它們,但現在它禁止你傳送任何引數。
debug_print("Hey");
這會引起一些語法錯誤,因為巨集期望至少再有一個引數,並且前處理器不會忽略 debug_print()
巨集中缺少逗號。此外 debug_print("Hey",);
會引發語法錯誤,因為你無法將引數傳遞給巨集為空。
為了解決這個問題,引入了 ##__VA_ARGS__
巨集,該巨集指出如果不存在變數引數,則前處理器從程式碼中刪除逗號。
例:
#define debug_print(msg, ...) printf(msg, ##__VA_ARGS__) \
printf("\nError occured in file:line (%s:%d)\n", __FILE__, __LINE)
用法:
debug_print("Ret val of somefunc()?");
debug_print("%d",somefunc());