【问题标题】:Make c++ macro2 containt quoted body of macro1使 c++ 宏 2 包含宏 1 的引用体
【发布时间】:2015-06-14 11:44:38
【问题描述】:

我正在尝试制作某种简单的系统来计算构建数量,包括 .rc 文件中的此信息(对于 Windows)并遇到了问题。这里是:

#define QUOTE(s) #s
#define A       0,0,0,1
#define A_STR   QUOTE(A)

A_STR 的扩展:"A" 但不是"0,0,0,1",正如我预期的那样。

好吧,我需要 A_STR 成为 A 的字符串表示形式(这就是 windres 期望在 .rc 文件中看到的内容),但我找不到这样做的方法。

我已经尝试过像#define A_STR #A 这样的东西,但它只是扩展为#0,0,0,1

我也尝试像这样使用 qmake:DEFINES *= A_STR="<here-is-how-I-get-version>"gcc 得到它没有引号,我也遇到了同样的问题。

【问题讨论】:

    标签: c++ gcc c-preprocessor qmake


    【解决方案1】:

    当扩展 C 预处理器宏时,它的参数会扩展为其文字参数,因此当您的 QUOTE(s) 接受参数 A 扩展时,s 将扩展为 A。通常,在此展开完成后,展开的文本会被再次扫描以展开其中嵌入的任何宏,因此这将导致A 展开为0,0,0,1。但是,当使用字符串化运算符# 对后面的文本进行字符串化时,该字符串化首先发生,因此后面的文本永远没有机会被扩展,因此您将字符串化"A" 作为A_STR 的最终扩展。

    这个问题通常通过引入第二级间接来解决,这给了初始宏参数第二次扩展的机会:

    #define QUOTE2(A) #A
    #define QUOTE(A) QUOTE2(A)
    

    但是,这实际上不适用于您的情况,因为在第一级扩展中,A 将扩展为 0,0,0,1,这将被视为 QUOTE2() 的四个参数,因此将被拒绝为一个无效的宏调用。

    您可以使用可变参数宏参数和__VA_ARGS__ 来解决这个问题:

    #define QUOTE2(...) #__VA_ARGS__
    #define QUOTE(...) QUOTE2(__VA_ARGS__)
    

    【讨论】:

    • 有效!特别感谢您对扩展过程的精彩解释!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-29
    • 1970-01-01
    • 2023-03-06
    • 2017-12-21
    相关资源
    最近更新 更多