C99中带有0个参数的变量宏

Mic*_*ior 10 macros c99 variadic

我有一些调试代码如下所示:

#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define AT __FILE__ ":" TOSTRING(__LINE__)
void __my_error(const char*loc, const char *fmt, ...);
#define my_error(fmt, ...) __my_error(AT, fmt, ##__VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)

使用最后一个宏,因此我可以将位置插入到调试输出中,以确定错误发生的位置.但是,当我调用这样的函数时:

my_error("Uh oh!");
Run Code Online (Sandbox Code Playgroud)

喜欢我的代码是C99,所以我觉得这个时候编译,我得到以下错误:

error: ISO C99 requires rest arguments to be used
Run Code Online (Sandbox Code Playgroud)

我知道我可以通过改变呼叫来解决这个问题

my_error("Uh oh!", NULL);
Run Code Online (Sandbox Code Playgroud)

但有什么方法可以让这个看起来不那么难看?谢谢!

sch*_*hot 14

我看到了这个问题的两种解决方案.(三,如果算上'坚持使用gcc').

特殊情况宏

当您想要打印固定字符串时添加新宏.

#define my_errorf(str) my_error(str, NULL)
Run Code Online (Sandbox Code Playgroud)

Pro:额外代码的最小数量.
Con:使用错误的宏很容易(但至少在编译时会注意到这一点).

fmt'......'放进去

Vararg宏只能有__VA_ARGS__作为参数(与vararg函数不同).因此,您可以将fmt参数放在__VA_ARGS__中并更改您的函数.

void __my_error(const char *loc, ...);
#define my_error(...) __my_error(AT, __VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)

Pro:所有错误消息的一种语法/宏.
Con:需要重写您的__my_error功能,这可能是不可能的.

  • Vararg 宏*可以*不仅仅有 __VA_ARGS__ 作为参数。例如,您可以传递 FILE* (对于 fprintf)或 char[] (对于 snprintf)。只是 ... 必须匹配至少一个参数,至少在 gcc 对 C99 的解释中是这样。 (2认同)