1. 简介
No. |
宏定义 |
作用 |
所属头文件 |
1 |
offsetof |
获取结构体中成员的偏移位置 |
stddef.h |
2 |
container_of |
根据成员的地址来获取结构体的地址 |
linux/kernel.h |
2. 宏定义offsetof
- 示例:结构体
struct foo
中每个成员的偏移地址。
/* offsetof example */
#include <stdio.h> /* printf */
#include <stddef.h> /* offsetof */
struct foo {
char a;
char b[10];
char c;
};
int main ()
{
printf ("offsetof(struct foo,a) is %d\n",(int)offsetof(struct foo,a));
printf ("offsetof(struct foo,b) is %d\n",(int)offsetof(struct foo,b));
printf ("offsetof(struct foo,c) is %d\n",(int)offsetof(struct foo,c));
return 0;
}
#define offsetof(type, member) (size_t)&(((type*)0)->member)
- 解析
将地址0
强制转换为type
类型的指针,member
定位到结构体中偏移位置。编译器认为0
是一个有效的地址,0
是type
指针的起始地址。
3. 宏定义container_of
- 示例:通过结构体
struct foo
中成员地址获取结构体地址。
/* container_of example */
#include <stdio.h> /* printf */
#include <linux/kernel.h> /* container_of */
struct foo {
char a;
char b[10];
char c;
};
int main ()
{
struct foo f;
printf ("struct foo f is %p\n",&f);
printf ("container_of(&(f.a),struct foo,a) is %p\n",container_of(&(f.a),struct foo,a));
printf ("container_of(&(f.b),struct foo,b) is %p\n",container_of(&(f.b),struct foo,b));
printf ("container_of(&(f.c),struct foo,c) is %p\n",container_of(&(f.c),struct foo,c));
return 0;
}
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
- 首先定义一个临时的数据类型(通过
typeof( ((type *)0)->member )
获得)与ptr
相同的指针变量__mptr
,然后用它来保存ptr
的值。
- 用
(char *)__mptr
减去member
在结构体中的偏移量,得到的值就是整个结构体变量的首地址(整个宏的返回值就是这个首地址)。