关于嵌套宏的问题
分别在不同的编译器上输出结果不相同,请问标准是否有相关说明?谢谢
- C/C++ code
#include <stdio.h>#define TO_STRING2(x) a_##x#define TO_STRING(x) TO_STRING1(x)#define TO_STRING1(x) #x#define PARAM(x) #x#define ADDPARAM(x) INT_##xint main(){ const char *str = TO_STRING(TO_STRING2(PARAM(ADDPARAM(1)))); printf("%s\n",str); return 0;}/*VS2010 output:a_PARAM(ADDPARAM(1))GCC 4.3.2 output:a_PARAM(INT_1)*/[解决办法]
C99 6.10.3.4有对宏嵌套的说明,不过写的比较难懂(PDF无法复制,也不想重打一遍)
个人理解,应该gcc是按标准执行的(CB的结果与gcc相同)
VS对很多C标准,没有执行
[解决办法]
改为:
- C/C++ code
#include <stdio.h>#define TO_STRING2(x) a_##x#define TO_STRING(x) TO_STRING1(x)#define TO_STRING1(x) T(x)#define T(x) #x#define PARAM(x) #x#define ADDPARAM(x) INT_##xint main(){ const char *str = TO_STRING(TO_STRING2(PARAM(ADDPARAM(1)))); printf("%s\n",str); return 0;}
[解决办法]
从输出来开,GCC的输出应该更符合标准,对宏参数的展开本身就应该是一个递归的过程,所以ADDPARAM应该得到展开。
如果宏定义以#开头,不展开参数,直接替换。
如果宏定义不以#开头,展开参数,直接替换,由外层向里层,如果碰到的是#开头的宏,不继续往里层展开,往外层展开。
由外层向里层,如果碰到的是以非#开头的宏,继续往里层走,直至最里层,开始一层层往外层展开。