我需要帮助做以下事情:
预处理器宏标签(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的井号(#)?
答案 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