代码之家  ›  专栏  ›  技术社区  ›  tuergeist

如何通过C预处理器打印磅/哈希?

  •  9
  • tuergeist  · 技术社区  · 16 年前

    #define label(x) ...
    

    如果我调用标签(aname),输出应为“#aname”(不带引号)

    我知道,以下尝试是错误的。

    #define label(x) #x   // leads to "x"
    #define label(x) \#x  // is \"x"
    #define label(x) "#x" // is "#x" (but not the content of x") "#otto"
    

    它可能存在一种逃脱的#(磅),但我不知道,如何逃脱。..

    编辑 :我运行“gcc-E test-o test.html”以获取输出。关键是:如何仅使用预处理器的功能打印出带有makro的哈希标记(#)?

    5 回复  |  直到 11 年前
        1
  •  13
  •   tuergeist    16 年前

    #define hash #
    #define f(x) x
    #define label(a) f(hash)a
    

    然后

    label(foobar)
    

    #foobar
    

    我是在…的帮助下找到的 你们所有人 ,尤其是冬哑巴。

        2
  •  4
  •   Jonathan Leffler    16 年前

    我认为你不能,这并非完全不合理,因为C预处理器的输出不应该产生未加引号的“#”,因为这将表示预处理器指令,而你不能像那样动态生成预处理器指令。

    换句话说,C预处理器是C(和C++)的预处理器,而不是一个完全通用的工具。

    使用其他宏处理器( m4

    例如,使用宏替换:

    #define label(x)    !@!x
    

    然后对输出进行后处理,替换“!@“!”加上“#”。

    (The imake 该节目使用了类似的特技;C预处理器完成了大部分工作,但它的输出没有保留“make”所需的换行符,因此“imake”使用符号“@@\”左右来指示在C预处理器做得最糟糕之后需要插入换行符的位置。)

        3
  •  4
  •   E.M.    16 年前

    #define f(x) x
    #define label(a) f(#)a
    

    我通过直接运行它来测试它 cpp (C预处理器)而不是通过 gcc 示例:

    cpp test > test.html
    

    使用gcc 4.0.1版本中的cpp。

    我注意到的唯一问题是,我得到了一些额外的不需要的输出,即文件的前4行如下:

    # 1 "test"
    # 1 "<built-in>"
    # 1 "<command line>"
    # 1 "test"
    
        4
  •  3
  •   Christoph    16 年前

    C中的字符串文字将被连接起来,所以你可以这样做

    #define label(x) "#" #x
    

    我认为没有字符串连接是不可能的(即没有像你想做的那样调用C编译器):

    你可以用额外的间接层做一些花哨的事情,我甚至让预处理器通过以下方式生成所需的输出

    #define hash #
    #define quote(x) #x
    #define in_between(c, d) quote(c ## d)
    #define join(c, d) in_between(c, d)
    #define label(x) join(hash, x)
    label(foo)
    

    in_between() 扩展到 #foo ,这不是有效的预处理器令牌。我看不出有什么办法。

    我的建议是为这项工作选择合适的工具:如果你喜欢冒险,或者使用PHP或Perl等脚本语言,可以切换到另一种宏语言,如m4,甚至ML/I。 GPP

        5
  •  1
  •   Neil    16 年前

    尝试:

    #define label(x) "#"x