今天看linux操作系统源码是有这么一段:
#define _syscall0(type,name) \
type name(void) \
{ \
long __res; \
__asm__ volatile ( "int $0x80" \// 调用系统中断0x80。
:"=a" (__res) \// 返回值??eax(__res)。
:"" (__NR_
##name)); \// 输入为系统中断调用号__NR_name。
if (__res >= 0) \// 如果返回值>=0,则直接返回该值。
return (type) __res; errno = -__res; \// 否则置出错号,并返回-1。
return -1;}
其中有一个地方出现了两个‘#’号不明白什么意思,网上找到了一段论坛:
宏中"#"和"##"的用法
一、一般用法
我们使用#把宏参数变为一个字符串,用##把两个宏参数贴合在一起.
用法:
#include<cstdio>
#include<climits>
usingnamespacestd;
#defineSTR(s)#s
#defineCONS(a,b)int(a##e##b)
intmain()
{
printf(STR(vck));//输出字符串"vck"
printf("%d
",CONS(2,3));//2e3输出:2000
return0;
}
二、当宏参数是另一个宏的时候
需要注意的是凡宏定义里有用'#'或'##'的地方宏参数是不会再展开.
1,非'#'和'##'的情况
#defineTOW(2)
#defineMUL(a,b)(a*b)
printf("%d*%d=%d
",TOW,TOW,MUL(TOW,TOW));
这行的宏会被展开为:
printf("%d*%d=%d
",(2),(2),((2)*(2)));
MUL里的参数TOW会被展开为(2).
2,当有'#'或'##'的时候
#defineA(2)
#defineSTR(s)#s
#defineCONS(a,b)int(a##e##b)
printf("intmax:%s
",STR(INT_MAX));//INT_MAX#include<climits>
这行会被展开为:
printf("intmax:%s
","INT_MAX");
printf("%s
",CONS(A,A));//compileerror
这一行则是:
printf("%s
",int(AeA));
INT_MAX和A都不会再被展开,然而解决这个问题的方法很简单.加多一层中间转换宏.
加这层宏的用意是把所有宏的参数在这层里全部展开,那么在转换宏里的那一个宏(_STR)就能得到正确的宏参数.
#defineA(2)
#define_STR(s)#s
#defineSTR(s)_STR(s)//转换宏
#define_CONS(a,b)int(a##e##b)
#defineCONS(a,b)_CONS(a,b)//转换宏
printf("intmax:%s
",STR(INT_MAX));//INT_MAX,int型的最大值,为一个变量#include<climits>
输出为:intmax:0x7fffffff
STR(INT_MAX)-->_STR(0x7fffffff)然后再转换成字符串;
printf("%d
",CONS(A,A));
输出为:200
CONS(A,A)-->_CONS((2),(2))-->int((2)e(2))
三、'#'和'##'的一些应用特例
1、合并匿名变量名
#define___ANONYMOUS1(type,var,line)typevar##line
#define__ANONYMOUS0(type,line)___ANONYMOUS1(type,_anonymous,line)
#defineANONYMOUS(type)__ANONYMOUS0(type,__LINE__)
例:ANONYMOUS(staticint);即:staticint_anonymous70;70表示该行行号;
第一层:ANONYMOUS(staticint);-->__ANONYMOUS0(staticint,__LINE__);
第二层:-->___ANONYMOUS1(staticint,_anonymous,70);
第三层:-->staticint_anonymous70;
即每次只能解开当前层的宏,所以__LINE__在第二层才能被解开;
2、填充结构
#defineFILL(a){a,#a}
enumIDD{OPEN,CLOSE};
typedefstructMSG{
IDDid;
constchar*msg;
}MSG;
MSG_msg[]={FILL(OPEN),FILL(CLOSE)};
相当于:
MSG_msg[]={{OPEN,"OPEN"},
{CLOSE,"CLOSE"}};
3、记录文件名
#define_GET_FILE_NAME(f)#f
#defineGET_FILE_NAME(f)_GET_FILE_NAME(f)
staticcharFILE_NAME[]=GET_FILE_NAME(__FILE__);
4、得到一个数值类型所对应的字符串缓冲大小
#define_TYPE_BUF_SIZE(type)sizeof#type
#defineTYPE_BUF_SIZE(type)_TYPE_BUF_SIZE(type)
charbuf[TYPE_BUF_SIZE(INT_MAX)];
-->charbuf[_TYPE_BUF_SIZE(0x7fffffff)];
-->charbuf[sizeof"0x7fffffff"];
这里相当于:
charbuf[11];
自己在linux下编写了一段程序:
#include<stdio.h>
#define transform 1##2##3
int main()
{
int result=transform*transform;
printf("the num of result is : %d",result);
return 0;
}
函数输出的结果是15129(=123*123)--得出结论是:##的作用之一是将前后两个宏参数连在一起!