关于宏##的使用注意一点

在看《C语言高级编程》时,里面有个关于宏##的题目:html

1.已知#define A “menu”
#define B “osd”,
若请使用宏A,B表示出字符串”menuosd”

答案:1 答案1:#define C A B
答案2:#define _C_(a,b) a##b
#define C(a,b) _C_(a,b)

 

而后我实际动手测试了一下,先来第一种:编程

#include <stdio.h>
#define A "menu"
#define B "osd"
#define STR A B

int main(int argc, char *argv[])
{
char *p = STR;
return 0;
}
gcc -E hell.c -o hello.i
cat hello.i

结果:测试

int main(int argc, char *argv[])
{


char *p = "menu" "osd";


return 0;
}

 

第一个答案其实预编译后给出的结果是不彻底符合要求的。google

而后是第二种:spa

#include <stdio.h>
#define A "menu"
#define B "osd"

#define _C_(a,b) a##b
#define C(a,b) _C_(a,b)

int main(int argc, char *argv[])
{
char *p = C(A,B);
printf("%s\n", p);
return 0;
}

 

首先,为何要定义两个宏,一个不能解决问题吗?是的,不能。为何?看这个连接:[短小精悍的宏](http://www.cnblogs.com/wb-DarkHorse/archive/2013/04/27/3046749.html)
而后再次按照上边的命令进行预编译,可是给出了错误信息:pasting "menu" and "osd" does not give a valid preprocessing token gcc
这就奇怪了。而后google了一下,发现了相同的问题:
[问题](http://stackoverflow.com/questions/4667779/preprocessor-macro-gcc-pasting-x-and-x-does-not-give-a-valid-preprocessing-toke)code

而且里面说了,这种状况在VS里面不会报错,能够直接工做。so?htm

#include <stdio.h>
#define A "menu"
#define B "osd"

#define _C_(a,b) a##b
#define C(a,b) _C_(a,b)

int _tmain(int argc, _TCHAR* argv[])
{
char *p = C(A,B);//STR;
printf("%s\n", p);
return 0;
}

 

果真给出告终果:menuosdblog

为何gcc和VS会对这个问题给出差别的结果呢?看这个问题:
[that's why](http://stackoverflow.com/questions/1206624/differences-in-macro-concatenation-operator-between-visual-c-and-gcc?rq=1)token

根据C标准,用##操做后的结果必须是一个已经预约义过的符号。不然是未定义的。因此gcc和vs对于这个未定义行为表示了不一样的见解,前者是给出错误,后者一笑而过。那什么是已经预约过的符号呢? 它包含了这些:头文件名, 等式, 预处理数字, 字符常数, 字符串值, 标点符号, 单个非空字符字符串

在咱们的例子中,_C_(a,b)用##链接后,应该是产生menuosd,可是这是一个未预约义的字符串,因此产生了一个未定义的行为。咱们再看一个例子:

#define A 2
#define _CONS(a,b) (a##e##b)
#define CONS(a,b) _CONS(a,b)

int main(int argc, char *argv[])
{
printf("%f\n", CONS(A, A));
return 0;
}

 

这个时候gcc不会给出错误提示了。结果:200.0000
为何这个时候不给出错误提示呢?个人理解是,CONS(A, A)替换后成为2e2,而这时一个常量,符合C标准。

ok,给出一个连接,详细的解释了gcc中##的用法:
[gcc concatenation](http://gcc.gnu.org/onlinedocs/gcc-4.3.3/cpp/Concatenation.html#Concatenation)

相关文章
相关标签/搜索