理解递归宏展开

4
我在一个嵌入式面试题集中看到了这个问题。
#define cat(x,y) x##y

x连接到y。但是cat(cat(1,2),3)没有展开,而是给出了预处理器警告。为什么?

C语言不鼓励递归宏扩展吗? 我的假设是表达式应该显示1##2##3。我错了吗?


3
递归展开仅适用于一级。请参见此处:自引用宏字符串化 - 0xF1
1
我非常想将这个问题关闭并标记为C预处理器和连接的重复,但是由于差别非常微小,我不想滥用我们已经拥有的像神一样的“标记为重复”的能力。不过,只需稍微劝说一下我就会改变主意。 - Jonathan Leffler
警告是正确的;你不能将一个右括号和数字3组合成一个令牌,而且令牌连接必须生成一个令牌。 - Jonathan Leffler
@JonathanLeffler 我同意这不是那个问题的重复,但肯定会有类似的问题。 - M.M
1个回答

3
问题在于cat(cat(1,2),3)并没有按照正常方式展开,你期望cat(1,2)会给出12cat(12, 3)会给出123在替换列表中前面或后面带有##的宏参数不会在替换时展开。因此,cat(cat(1,2),3)展开为cat(1,2)3,这不能进一步展开,因为没有名为cat(1,2)3的宏
所以简单的规则是,依赖于##的替换列表的宏通常无法以嵌套式调用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接