【问题标题】:C variadic macroC 可变参数宏
【发布时间】:2015-11-22 08:45:25
【问题描述】:

我在下面定义了两个可变参数宏用于调试打印。

#define MYTRACE(fmt, args...) printf("%s(): "fmt"\n", __func__, ##args)
#define MYTRACE_ERR(err, fmt, args...) printf("[ERR] %s(): "fmt" err=%d\n", __func__, ##args, err)

Second 不仅显示消息,还显示给第一个参数的错误代码。 使用它们,我编写了以下代码。

int main(void) {
    int err = 0;

    MYTRACE("this is test, err=%d.", err);
    MYTRACE();
    MYTRACE_ERR(err, "error!");
    MYTRACE_ERR(err);        // This becomes error.
    MYTRACE_ERR(err, "");    // This is OK.
}

此代码无法编译,因为MYTRACE_ERR(err); 成为宏使用错误,但MYTRACE(); 不是。 为避免错误,MYTRACE_ERR 似乎至少需要两个参数。

我不明白为什么MYTRACE 工作,即使没有给出参数,但如果没有给出两个参数,MYTRACE_ERR 不起作用。

【问题讨论】:

  • ...我不明白你为什么要使用宏!
  • 你正在使用两个 gcc 扩展,如果你想编写可移植的代码,你不应该这样做:args... 来命名参数,##args 来吃逗号。我认为两者行为不同的原因是显而易见的。您的第二个变体在##args 构造之后有err,所以它需要它。我对 gcc 的细节不够熟悉,无法帮助您纠正这个问题。但是您也许应该在 SO 中搜索“调试宏”左右以找到可移植的代码。类似的问题不时出现。

标签: c gcc c-preprocessor variadic-macros


【解决方案1】:

根据:https://gcc.gnu.org/onlinedocs/cpp/Macro-Arguments.html

您可以将宏参数留空;这不是错误 预处理器(但许多宏随后将扩展为无效代码)。你 不能完全忽略论点;如果一个宏有两个参数, 其参数列表的顶层必须只有一个逗号。

使用MYTRACE_ERR(err,); 将编译!

另外,定义可变参数宏的正确方法应该如下:

#define MYTRACE(fmt, ...) printf("%s(): "fmt"\n", __func__, ##__VA_ARGS__)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-11
    • 1970-01-01
    相关资源
    最近更新 更多