C预处理器宏扩展

时间:2017-07-28 13:51:06

标签: c macros c-preprocessor

我很难理解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 

我猜这里有某种“只能扩展同名宏”的规则吗?我能做些什么来让宏扩展我想要的方式吗?

2 个答案:

答案 0 :(得分:3)

C99草案说宏观扩张不允许递归:

  

6.10.3.4重新扫描和进一步更换

     
      
  1. 替换列表中的所有参数均已替换   #和   已经进行##处理,删除了所有地标预处理令牌。生成的预处理标记序列   然后重新扫描,以及所有后续预处理   源文件的标记,用于替换更多的宏名称。
  2.   
  3. 如果   在此扫描期间找到要替换的宏的名称   替换列表(不包括源文件的其余部分   预处理令牌),不替换。此外,如果有的话   嵌套替换遇到要替换的宏的名称,它   没有被替换。这些无法替换的宏名称预处理   令牌不再可用于进一步更换,即使它们   稍后(重新)检查宏名称的上下文   否则,预处理令牌将被替换。
  4.   

所以X(A(A(x)))扩展为"A" _A(x),但正如您所见,扩展本身并未扩展。

答案 1 :(得分:3)

当我想要进行宏扩展时,我通常使用这个图,我使用标准中的第6.10.3节构建。希望它有所帮助...

enter image description here

正如Toby已经提到的,嵌套宏不会递归扩展。