【问题标题】:How to parametrize single string containing # in C preprocessor?如何在 C 预处理器中参数化包含 # 的单个字符串?
【发布时间】:2017-11-10 10:30:33
【问题描述】:

我想为 IBM Metal C Prolog 创建参数化预处理器宏。

初始无参数形式是 #pragma prolog(Foo, " #MCPROLG MAIN=(YES,16,132)") 真正的序言更复杂,但为了这个问题,重要的部分是字符串中有值。

#pragma 指令本身不能成为宏的一部分,因此我将其替换为_Pragma,如下所示: _Pragma("prolog(Foo, \" #MCPROLG MAIN=(YES,16,132)\")")

我可以像这样参数化 Foo:

#define STR(...) #__VA_ARGS__
#define PROLOG(function) _Pragma(STR(prolog( function , " #MCPROLG MAIN=(YES,16,132)")))

如何创建参数化值 16 的宏?

看来我需要在预处理器中连接字符串,我尝试了以下方法。都使用这个字符串化宏:

#define STR(...) #__VA_ARGS__
  1. 替换为 16 的标记(我们将其命名为 size)不能在字符串本身内,因此它会被替换。

    #define PROLOG(function, size) _Pragma(STR(prolog( function , "#MCPROLG MAIN=(YES, size ,132)")))

  2. _Pragma 只接受一个字符串,所以我不能像这样细读 C 字符串连接:

    #define PROLOG(function, size) _Pragma(STR(prolog( function , " #MCPROLG MAIN=(YES," #size ",132)")))

  3. 我不能像这样对 prolog 的整个第二个参数进行字符串化:

    #define PROLOG(function, size) _Pragma(STR(prolog( function , STR(#MCPROLG MAIN=(YES, size ,132)))))

因为#MCPROLG 需要保留在字符串中,这样它的# 就不会被视为字符串化标记。

【问题讨论】:

    标签: c-preprocessor metalc


    【解决方案1】:

    要解决问题1(需要在替换列表中扩展一个参数),您需要一个间接字符串化宏:

    #define STR(X) STR_I(X)
    #define STR_I(X) #X
    

    如果你愿意,你可以使这个可变参数,但这里没有必要(你的字符串中的逗号被括号括起来;预处理器将匹配那些;例如,FOO(A=(B,C,D)),因为FOO 是一个类似函数的宏,有一个论点)。

    要解决问题 2,是的,您需要对整个事情进行字符串化。实际上,没有将字符串文字连接到预处理器(因为它在翻译阶段 4 中运行,而字符串文字连接直到翻译阶段 6 才会发生)。

    要解决问题 3,只需从另一个宏生成哈希(将其根植于类似对象的宏,其中# 没有特殊含义):

    #define HASH #
    #define HASHM() HASH
    

    类似函数的变体允许您在其他内容旁边生成相同的哈希(HASHMCPROLG 没有任何用处;HASH MCPROLG 生成 # MCPROLGHASHM()MCPROLG 生成 #MCPROLG)。

    这些东西在手,剩下的很简单:

    #define PROLOG(FN_,SZ_) _Pragma(STR(prolog(FN_, STR( HASHM()MCPROLG MAIN=(YES,SZ_,132)))))
    

    在这里,我假设您还需要在 pragma prolog 周围加上一个结束括号,并且在问题中这是一个错字;也就是说,它应该是:

    _Pragma("prolog(foo, \"#MCPROLG MAIN=(YES,16,132)\")")
    

    ...不是:

    _Pragma("prolog(foo, \"#MCPROLG MAIN=(YES,16,132)\"")
    

    【讨论】:

    • 感谢产生哈希的宏,它成功了。你对括号是正确的,还有一些额外的参数,比如我为了简洁而排除的主组,并且未能平衡括号。我已经更正了这个问题。
    猜你喜欢
    • 1970-01-01
    • 2017-02-25
    • 2011-11-15
    • 1970-01-01
    • 2011-10-22
    • 1970-01-01
    • 2012-06-03
    • 2019-06-21
    相关资源
    最近更新 更多