在Linux Kernel中,经常看到“##”和“#”,也知道是连接符,就是直接把两个字符串连接起来的意思,但感觉还是理解不透澈,google一下做记录:
1、预处理运算符
#、##和#@是预处理运算符,他们三者的作用分别是:
- #(单井号) —— 字符串化运算符。
- ##(双井号 )—— 连接运算符
- #@ —— 字符化运算符。(非ANSI C标准,gcc不支持)
这意味着,如果你在c/c++源码中使用这三个符号,那么在预处理阶段将三个符号的作用域产生一些字符(串)替换类操作,具体看下面的例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#include <stdio.h>
#include <string.h>
#define STR(x) #x
#define PRINT_TWO_STR(a,b) printf("%s\n", STR(a##b))
int
main()
{
printf
(
"%s\n"
, STR(just a test));
PRINT_TWO_STR(i want, money);
return
0;
}
|
仅仅预处理的结果是:
1
2
3
4
5
6
7
8
|
int
main()
{
printf
(
"%s\n"
,
"just a test"
);
printf
(
"%s\n"
,
"i wantmoney"
);
return
0;
}
|
通俗一点,#的作用在与替换双引号,##用于连接两个字符。
2、用法
在Linux内核中,##的一种用法是define定义一系列函数,这些函数在名字上很相似,只有部分不一样,例如:
1
2
3
4
5
6
7
|
#define BRPORT_ATTR(_name,_mode,_show,_store) \
const
struct
brport_attribute brport_attr_##_name = { \
.attr = {.name = __stringify(_name), \
.mode = _mode }, \
.show = _show, \
.store = _store, \
};
|
另一种用法,用于定义使用printk等参数数量不定的宏:
1
2
|
#define ARB_PRINTK(format, args...) \
printk(KERN_DEBUG format , ## args)
|