c带有多个可选参数的宏

时间:2014-09-17 15:46:08

标签: c printf c-preprocessor

我正在尝试编写一个调试打印宏,它将打印函数名称,并选择包含format / varargs来打印参数。

我已经设置了我的模块,通过在各个模块中添加样式变量并在打印宏中使用它,每个模块都有打印颜色。

工作打印宏如下

//myprint.h
...
#define STYLE_UNDERLINE "\033[4m"
#define STYLE_NORMAL    "\033[0m"

#define STYLE_BLUE      "\033[0;34m"
... // more colo(u)rs here

#define PRINTF(fmt, ...) printf("%s" fmt STYLE_NORMAL, style, ##__VA_ARGS__)
...

用法:

//myfile.c
...
static char * style = STYLE_BLUE;

void myFunc(int i) {
    PRINTF("String with no params\n");
    PRINTF("i value %d\n", i);
}

我想用PRINT_FN宏做类似的事情,如下所示

//myfile.c
...

void myFunc(int i) {
    PRINT_FN();       // just print the function name
    // equivalent to
    PRINTF("%s%s()", STYLE_UNDERLINE, __func__);

    PRINT_FN("%d", i) // print the function name and parameter
    // equivalent to
    PRINTF("%s%s(%d)", STYLE_UNDERLINE, __func__, i);
}

我可以找出一个几乎可以实现这个目标的宏,问题是它需要你最小化地发送一个空格式字符串。

#define PRINT_FN(fmt, ...) printf("%s" STYLE_UNDERLINE "%s(" fmt ")" STYLE_NORMAL, \
                                  style, __func__, ##__VA_ARGS__)

有没有办法让fmt参数可选?

1 个答案:

答案 0 :(得分:2)

请勿尝试将所有内容整合到一个printf中。分开装饰品和实际输出:

#define PRINT_FN(...)                                   \
    do {                                                \
        printf("%s%s: ", STYLE_UNDERLINE, __func__);    \
        printf("" __VA_ARGS__);                         \
        printf("%s\n", STYLE_NORMAL);                   \
    } while (0)

如果格式为空,则连接空字符串会导致空字符串,否则会导致原始格式。然而,gcc的-Wall设置会警告空格式字符串。

编译do ... while shold并用于制作宏behave as one statement。也许你的情况有点过分,但仍然存在。