第31课 - 老生常谈的两个宏

Posted Hengs

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第31课 - 老生常谈的两个宏相关的知识,希望对你有一定的参考价值。

第31课 - 老生常谈的两个宏

1. Linux 内核中常用的两个宏定义

1.1 offsetof 宏

  • include/linux/stddef.h 头文件中定义
  • TYPE 是结构体类型、MEMBER 是结构体中一个成员的成员名
  • 作用:offsetof 宏返回的是 MEMBER 成员相对于整个结构体变量的首地址的偏移量,类型是 size_t(unsigned int)
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

1.2 container_of 宏

/**
 * container_of - cast a member of a structure out to the containing structure
 * @ptr:	the pointer to the member.
 * @type:	the type of the container struct this is embedded in.
 * @member:	the name of the member within the struct.
 *
 */
#define container_of(ptr, type, member) ({				const typeof( ((type *)0)->member ) *__mptr = (ptr);		(type *)( (char *)__mptr - offsetof(type,member) );})
  • include/linux/kernel.h 头文件中定义
  • type 是结构体类型、member是该结构体的某一个成员、ptr 是指向成员 member 的指针
  • container_of 宏使用 offsetof 宏完成其功能
  • 作用:container_of 宏通过结构体变量中一个成员的地址得到这个结构体变量的首地址

  上面这两个宏在 Linux 内核中非常常见,比如 linux 内核链表 list_head、工作队列 work_struct 中。乍一看,这两个宏给人感觉很复杂,尤其是 container_of 宏。其实,再复杂的结构也是由简单的东西构造而成的,下面我们就一层一层的剥开这两个宏的真相!!!

2. 逐步分析这两个宏

2.1 分析 offsetof 宏

  offsetof 用于计算 TYPE 结构体中 MEMBER 成员的偏移位置。

  第一次看到这个宏定义,第一反应就是直接使用 0 地址不会导致程序崩溃吗?

 

以上是关于第31课 - 老生常谈的两个宏的主要内容,如果未能解决你的问题,请参考以下文章

第46课 函数与宏分析

第56课 函数模板的概念和意义

第31课 std::atomic原子变量

Redis2.6源代码走读第007课:压缩列表02

第56课 函数模板的概念和意义

inline内联函数