具有多个可选参数的 c 宏

标签 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 参数成为可选参数?

最佳答案

不要试图将所有内容都塞进一个 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 应该被编译掉并用于生成宏 behave as one statement .在你的情况下可能有点矫枉过正,但仍然如此。

关于具有多个可选参数的 c 宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25895002/

相关文章:

c - 如何在 Eclipse IDE 中运行简单的 C 程序

C - 如何限制堆中的地址访问?

c - 以下 C 代码段的输出是什么?

java - String.format 和数组

c - 在 gcc 中使用嵌套循环时 printf 不起作用

c - 在 printf 中显示字符串而不是数字 (C)

c - 将 +/- 字母等级定义为常量。 C

c - 预处理器##运算符和变量

C++预处理器

c - 未在 header 中公开的静态库中的函数是否可访问?