【问题标题】:Using #ifdef on token-pasted macros?在标记粘贴的宏上使用#ifdef?
【发布时间】:2019-06-26 17:06:15
【问题描述】:

我知道已经有一篇与我类似的帖子 (C++ `ifdef` with concatenation of macros values),但该帖子已经很老了,提供的解决方案对我不起作用,因为我无法设置我想要检查的定义。所以我希望有人可以帮助我。

问题是我想用一个固定的文本来连接两个 a 的 ifdef。

想象一下下面的代码

#define ENABLE_MODULE_1

enum Modultype
{
    MODULE_1,
    MODULE_2
};

#define MODULE MODULE_1


int main()
{
    #ifdef ENABLE_ ## MODULE
    printf("NAME defined");
    #else
    printf("NAME not defined");
    #endif
    return 0;
}

所以我基本上想检查ENABLE_MODULE_1 是否基于MODULE 定义。

我希望有人可以帮助我。谢谢!

【问题讨论】:

  • 请提供旧帖的链接。而且你不能在预处理器中使用预处理器。
  • ## 运算符特定于类函数宏的替换列表。您不能(直接)在条件包含指令中使用它。
  • 你仍然做不到 - 为什么不问一个关于失败的解决方案的问题呢?
  • 这是您指的问题吗? stackoverflow.com/questions/34109448/…
  • 您能否解释一下为什么@templatetypedef 链接的问题中的解决方案对您不起作用?

标签: c c-preprocessor


【解决方案1】:

这是不可能的。预处理器宏仅扩展一次,并且仅在不在另一个预处理器语句中时扩展。除此之外,连接只能在#define 语句中使用。

【讨论】:

    【解决方案2】:

    您无法精确地做您想做的事,因为#ifdef 操作的是标识符,而不是预处理器表达式,而且## 运算符只能用于宏定义的替换文本。

    如果您愿意使用非零常量定义ENABLE_MODULE_1(如果有定义的话)作为其替换文本,您可以实现类似于您想要的内容,如下所示:

    #include <stdio.h>
    
    #define XENABLED(x)         ENABLE_ ## x
    #define ENABLED(x)          XENABLED(x)
    
    #define XSTR(x)             #x
    #define STR(x)              XSTR(x)
    
    #define ENABLE_MODULE_1     1   /* enabled */
    #define ENABLE_MODULE_3     0   /* not enabled */
    
    #define MODULE              MODULE_1
    #define OTHER               MODULE_2
    #define ANOTHER             MODULE_3
    
    int main(void)
    {
    #if ENABLED(MODULE)
        printf("%s enabled\n", STR(MODULE));
    #else
        printf("%s not enabled\n", STR(MODULE));
    #endif
    #if ENABLED(OTHER)
        printf("%s enabled\n", STR(OTHER));
    #else
        printf("%s not enabled\n", STR(OTHER));
    #endif
    #if ENABLED(ANOTHER)
        printf("%s enabled\n", STR(ANOTHER));
    #else
        printf("%s not enabled\n", STR(ANOTHER));
    #endif
    #if ENABLED(UNDEFINED)
        printf("%s enabled\n", STR(UNDEFINED));
    #else
        printf("%s not enabled\n", STR(UNDEFINED));
    #endif
        return 0;
    }
    

    上述程序产生以下输出:

    MODULE_1 enabled
    MODULE_2 not enabled
    MODULE_3 not enabled
    UNDEFINED not enabled
    

    【讨论】:

    • 感谢您的建议!不幸的是,我无法设置ENABLE_MODULE_1,因为它是在我无权访问的配置文件中给出的。因此,我一直在寻找一个通用的解决方案,这样我就不必手动检查每个 ENABLE,但显然这无法完成。无论如何,非常感谢您的努力。
    • @EmbedEngineer 我添加了一个使用defined() 的变体,可能会对您有所帮助。
    • @IanAbbott 请注意,就标准而言,使用defined(...) 的解决方案会调用未定义的行为:“如果令牌defined 是由于[控制表达式中的宏替换#if#elif],行为未定义”(C89 6.8.1、C99 和 C11 6.10.1)。是的,在标准 C 中,您可以在编译期间调用未定义的行为;是的,这很愚蠢。
    • @AlexShpilkin 感谢您提供信息。我会删除那部分。
    猜你喜欢
    • 2021-11-13
    • 1970-01-01
    • 2011-03-24
    • 1970-01-01
    • 1970-01-01
    • 2022-12-18
    • 1970-01-01
    • 1970-01-01
    • 2017-03-05
    相关资源
    最近更新 更多