【问题标题】:Generate #ifdef, #endif clause with another macro使用另一个宏生成#ifdef、#endif 子句
【发布时间】:2023-04-05 03:29:02
【问题描述】:

我正在处理的程序有问题。我正在尝试在 --help 中显示是否编译了哪些功能。但是,其中有很多,“正常”的方式太冗长了。例如:

#ifdef HAVE_FOO
static const bool have_foo = true;
#else
static const bool have_foo = false;
#endif
printf("Support for foo: %s\n", have_foo ? "yes" : "no");

现在,由于我基本上必须对每个功能都执行此操作,因此会出现很多行,这是我不想要的。

所以我想我会为它写一些宏:

#define _SUPP(X) #ifdef HAVE_##X \
static const bool _##X##_SUPP = true; \
#else \
static const bool _##X##_SUPP = false; \
#endif

#define _PRINTSUPP(var, name, desc) printf("\t%s - %s: %s\n", name, desc, _##var##_SUPP ? "yes" : "no")

但是,这里有一个问题。宏将扩展为单行,预处理器对此感到窒息。有没有办法生成一个中间有实际换行符的宏,或者是否可以在一行上评估 #ifdef

【问题讨论】:

    标签: c macros c-preprocessor


    【解决方案1】:

    如果不是不定义HAVE_FOO,而是将其定义为0,您可以这样做:

    const struct {
        bool present;
        const char *name;
    } features[NFEATURES] = {
        {HAVE_FOO, "foo"},
        {HAVE_BAR, "bar"},
        ...
    };
    
    for (size_t i=0; i < NFEATURES; i++)
        if (features[i].present)
            printf(" ... and we've got: %s\n", features[i].name);
    

    然后,您必须检查 #if HAVE_FOO 而不是 #ifdef HAVE_FOO,如果您的功能数量以数计运行,您的 --help 消息可能会显示得慢一些(在这种情况下,我建议您使用反正不同的架构)。

    【讨论】:

    • 猜你在features 的声明中缺少[],不是吗?
    【解决方案2】:

    你不能在 C 中做到这一点。通常的方法是从 Perl 或 Python 等文本描述中生成这样的标题。

    【讨论】:

      【解决方案3】:

      您不能使用宏来创建另一个预处理指令。在宏扩展开始之前,所有预处理指令都会被识别,因此您的宏将被解释为错误的 C 代码。

      【讨论】:

        猜你喜欢
        • 2010-11-12
        • 1970-01-01
        • 1970-01-01
        • 2010-12-20
        • 1970-01-01
        • 2014-10-16
        • 1970-01-01
        • 2021-10-29
        • 1970-01-01
        相关资源
        最近更新 更多