About ## preprocessor in C

孤街浪徒 提交于 2019-12-06 20:00:02

问题


Given

#define cat(x,y) x##y

The call cat(a,1) returns a1, but cat(cat(1,2),3) is undefined. However if I also define #define xcat(x,y) cat(x,y), then the result of xcat(xcat(1,2),3) is now 123. Can anybody please explain in detail why this is so?


回答1:


I tested this using both GCC and Clang.

GCC gives the error:

test.c:6:1: error: pasting ")" and "3" does not give a valid preprocessing token

Clang gives the error:

test.c:6:11: error: pasting formed ')3', an invalid preprocessing token
  int b = cat(cat(1,2),3);

What appears to be happening is that the compiler wraps the result of cat(1,2) in parentheses as soon as it is expanded; so when you call cat(1,2) in your code, it really gives you (12). Then, calling cat((12),3) again leads to ((12)3), which is not a valid token, and this results in a compile error.

The common opinion is "when using the token-pasting operator (##), you should use two levels of indirection" (i.e., use your xcat workaround). See Why do I need double layer of indirection for macros? and What should be done with macros that need to paste two tokens together?.




回答2:


In xcat(x,y), the x and y are not adjacent to the ## operator, and so they undergo macro expansion before being substituted.

So x is identified as xcat(1,2) and y is identified as 3. But prior to substitution, x is macro-expanded to cat(1,2), which turns into 1##2 which turns into 12. So ultimately, xcat(xcat(1,2),3) will expand to cat(12,3), which will turn out 123.

This Works --> cat(xcat(1,2),3) --> cat(cat(1,2),3) --> cat(12,3)

The behavior is well-defined because all of the token pastings result in valid preprocessor tokens i.e any expanded xpression should be a valid token at any stage.




回答3:


I don't think if cat is actually gonna be expanded for 2 consecutive times. That's why I wonder why would compiler even produce such a message like 'pasting ")" and "3" does not give a valid preprocessing token'. Also, I don't think the inner cat is gonna be expanded first. So, I presume the output would be cat(1,2)3. That direct me to cogitate how would the compiler interpret this.



来源:https://stackoverflow.com/questions/11037153/about-preprocessor-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!