我很难理解在以下情况下C预处理程序如何应用重写规则。我有以下宏:
#define _A(x) "A" _##x
#define _B(x) "B" _##x
#define X(x) _##x
这个想法是,每个宏都使用串联来创建一个新的表达式,该表达式本身可以是一个宏-如果它是一个宏,我希望将其扩展:
现在,以下扩展如我所料:
X(x) expands to _x
X(A(x)) expands to "A" _x
X(A(B(x))) expands to "A" "B" _x
但是,一旦再次使用同一宏,则使用一次,扩展将停止:
X(A(A(x))) expands to "A" _A(x), expected "A" "A" _x
X(B(B(x))) expands to "B" _B(x), expected "B" "B" _x
X(A(B(A(x)))) expands to "A" "B" _A(x), expected "A" "B" "A" _x
X(A(B(A(B(x))))) expands to "A" "B" _A(B(x)), expected "A" "B" "A" "B" _x
我猜这里有某种“只能扩展一次同名宏”规则吗?我可以做些什么来使宏扩展我想要的方式吗?
最佳答案
C99草案说,在宏扩展中不允许递归:
6.10.3.4重新扫描并进一步替换
在替换列表中的所有参数被替换后,
#
和
##
处理已经进行,所有地标预处理标记均已删除。产生的预处理令牌序列
然后重新扫描,以及所有后续预处理
源文件的令牌,用于替换更多的宏名称。
如果
在此扫描过程中找到了要替换的宏的名称
替换列表(不包括源文件的其余部分
预处理令牌),则不会替换它。此外,如果有的话
嵌套替换遇到要替换的宏的名称,它
不被替换。这些不可替换的宏名称预处理
令牌不再可用于进一步替换,即使它们
稍后在该宏名称的上下文中进行(重新)检查
否则将替换预处理令牌。
因此,X(A(A(x)))
扩展为"A" _A(x)
,但正如您所见,该扩展本身并不是扩展的。