为了更清晰的错误处理我使用宏(它使用C99和GCC扩展);行为类似于标准assert
:
#define A(cond, msg, ...) ({ \
if (!(cond)) { \
if (msg) \
say(msg, ##__VA_ARGS__); \
else \
say("Error at file %s, function %s, line %u: %s", \
__FILE__, __func__, __LINE__, #cond); \
A_RETURN(); \
} \
})
其中say
是格式化输出。并使用它:
#undef A_RETURN
#define A_RETURN() ({ fclose(f); free(p); return false; })
A(foo() != FOO_ERROR, 0);
A(bar() != BAR_ERROR, "bar failed");
当我没有特定的错误消息时,我必须写A(cond, 0)
。但我想在这种情况下只写A(cond)
。如何为此行为修改我的A
宏?即我需要一种方法来检查msg
参数是否未传递给宏。
答案 0 :(得分:1)
在suggested question的帮助下,我发现你可以像这样修改你的宏。
#define A() .... //your macro
#define A_CALC_ARG_IMPL(_1,N,...) N
#define A_CALC_ARG(...) A_CALC_ARG_IMPL(__VA_ARGS__,0)
#define A_NEW(...) A(cond, A_CALC_ARG(__VA_RGS__))
因此,如果您未通过A_NEW
,则新的A(cond, 0)
微距调用将扩展为msg
。
可以很好地解释Variadic宏at this blog。