變元論證巨集

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());