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

时间:2009-09-06 20:10:29

标签: c c-preprocessor

我需要帮助做以下事情:

预处理器宏标签(x)应输出“#x”,例如

#define label(x) ...

如果我调用label(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 个答案:

答案 0 :(得分:13)

答案是:

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

然后

label(foobar)

创建

#foobar

我是在你们所有人的帮助下找到的,但特别是冬季静音。 非常感谢!

(使用gcc 4.3.3)

答案 1 :(得分:4)

我认为你不能,这不完全是不合理的,因为C预处理器的输出不应该产生一个不带引号的'#',因为它表示一个预处理器指令,你不能生成预处理器指令那样的飞。

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

要么使用替代宏处理器(m4是类Unix系统的标准建议),要么采用不同的方式。

例如,有宏替换:

#define label(x)    !@!x

然后后处理输出替换'!@!'用'#'。

imake程序使用类似的特技; C预处理器完成大部分工作,但其输出不保留'make'所需的换行符,因此'imake'使用符号'@@在C预处理器完成最坏的情况之后,指示需要插入换行符的位置。)

答案 2 :(得分:4)

您可以这样做:

#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"

答案 3 :(得分:3)

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时,它也会生成错误消息,{{1}}不是有效的预处理器令牌。我没有看到任何解决方法。

我的建议是为工作选择合适的工具:如果您喜欢冒险或使用像PHP或Perl这样的脚本语言,请切换到另一种宏语言,如m4甚至ML / I. GPP似乎也很好,可能更适合。

答案 4 :(得分:1)

尝试:

#define label(x) "#"x