分享程序员开发的那些事...
首页
NTFS
漏洞
Android
Magento
服务器
Python
powershell
技术问答
Linux
网站首页
且构网 - 分享程序员编程开发的那些事
您所在的位置:
首页
>
盘点Linux内核源码中使用宏定义的若干技巧(2)
盘点Linux内核源码中使用宏定义的若干技巧(2)
更新时间:2022-02-26 04:24:35
5. typeof和0指针
这个在大名鼎鼎的container_of就有出现,事实上一些面试题有时候也喜欢跟这个沾点边。
点击(
此处
)折叠或打开
#define offsetof
(
TYPE
,
MEMBER
)
(
(
size_t
)
&
(
(
TYPE
*
)
0
)
-
>
MEMBER
)
点击(
此处
)折叠或打开
#define container_of
(
ptr
,
type
,
member
)
(
{
\
const
typeof
(
(
(
type
*
)
0
)
-
>
member
)
*
__mptr
=
(
ptr
)
;
\
(
type
*
)
(
(
char
*
)
__mptr
-
offsetof
(
type
,
member
)
)
;
}
)
哦,看到没,这里就直接使用了大括号({...})。第一个宏offsetof用来获得一个结构体中某一成员MEMBER与该结构体起始地址的偏移量,这个用法很有创意,0指针,充分利用了编译器的技巧。比如下面的代码,输出的结果是4:
点击(
此处
)折叠或打开
struct test
{
int
a
;
int
b
;
}
;
int
main
(
void
)
{
printf
(
"offset_b = %ld\n"
,
(
size_t
)
(
&
(
(
struct test
*
)
0
)
-
>
b
)
)
;
return 0
;
}
typeof是gcc对C标准的一个扩展,用来告诉编译器你打算使用括号里面的变量类型。关于typeof的更详细说明请参考:
http://gcc.gnu.org/onlinedocs/gcc/Typeof.html
6. 宏参数的静态检查
下面的宏来自模块参数的定义部分:
点击(
此处
)折叠或打开
#define __module_param_call
(
prefix
,
name
,
ops
,
arg
,
isbool
,
perm
)
\
/
*
Default value instead of permissions
?
*
/
\
static
int
__param_perm_check_##name __attribute__
(
(
unused
)
)
=
\
BUILD_BUG_ON_ZERO
(
(
perm
)
0
|
|
(
perm
)
>
0777
|
|
(
(
perm
)
&
2
)
)
\
+
BUILD_BUG_ON_ZERO
(
sizeof
(
""
prefix
)
>
MAX_PARAM_PREFIX_LEN
)
;
\
static
const
char __param_str_##name
[
]
=
prefix #name
;
\
static struct kernel_param __moduleparam_const __param_##name
\
__used
\
__attribute__
(
(
unused
,
__section__
(
"__param"
)
,
aligned
(
sizeof
(
void
*
)
)
)
)
\
=
{
__param_str_##name
,
ops
,
perm
,
isbool
?
KPARAM_ISBOOL
:
0
,
\
{
arg
}
}
其中第3-5行定义了一个事实上并不会用到的变量__param_perm_check_##name,为了防止编译器产生未使用变量的警告,该变量后面使用了__attribute__((unused))属性。这个并不会使用到的变量在该宏中的唯一作用是对变量参数perm和prefix的大小进行一个静态检查,如果BUILD_BUG_ON_ZERO中的条件为TRUE,那么将会产生一个编译错误。
上一篇 : :STL - 函数作为算法的参数
下一篇 : C++ STL算法系列1---count函数
相关阅读
盘点Linux内核源码中使用宏定义的若干技巧(1)
盘点Linux内核源码中使用宏定义的若干技巧(2)
盘点Linux内核源码中使用宏定义的若干技巧(1)
盘点Linux内核源码中使用宏定义的若干技巧(2)
推荐文章
更多新特性,HPE Vertica8.0荣耀问世!
Symfony1.4.11学习笔记(三):设置虚拟机
分享Silverlight/WPF/Windows Phone一周学习导读(8月15日-8月19日)
《HTML5 canvas开发详解(第2版)》——2.12 检查一个点是否在当前路径
Windows7下找不到输入音频设备的解决方法
三句话告诉你 mapreduce 中MAP进程的数量怎么控制?
Properties文件及与之相关的System.getProperties操作(转)
利用函数指针实现C的回调函数,实现调用者和底层驱动的解耦
Sysdig:Linux服务器监控和排障利器
Android 清除缓存详细实现(显示缓存大小)