linux中常用的宏

前言:网上对这些宏的解释特别多,有些博客也写得特别精彩,不过为了加深理解,特地写一下分析过程。

offsetof

1、宏定义如下

/*
 * 宏包含两个参数:
 * --type 结构体类型
 * --member 结构体成员变量名
 */
 #define offsetof(type, member) ( (size_t)&(((type *)0)->member) )

2、作用:返回结构体type中member成员相对于结构体首地址的偏移量,以字节为单位。
3、解释:这个宏的精髓在于将0强制类型转换为type类型的指针,对编译器来说,存在一个首地址为0x00000000,类型为type的结构体。
4、分析分三步:
① ((type *)0)->member,存在一个起始地址为0x00000000,类型为type的结构体,它的成员变量member的
②&(((type *)0)->member),取结构体成员变量member的地址,并且对这个地址是相对0进行偏移的。
③(size_t)&(((type *)0)->member),对偏移值进行size_t类型转换。

container_of

1、宏定义如下

/*
 * 宏包含三个参数
 * --ptr 指向结构体成员变量member的指针
 * --type 结构体类型
 * --member 结构体成员变量名
 */
#define container_of(ptr, type, member) ({ \
		const typeof( ((type *)0)->member ) *__mptr = (ptr); \
		(type *)( (char*)__mptr - offsetof(type, member) ); \
})

2、作用:根据一个结构体变量中成员变量的指针来获取指向整个结构体变量的指针
3、解释:整个宏可以拆开成两部分
1> const typeof( ((type *)0)->member ) *__mptr = (ptr);
① typeof是用来获取成员变量member的数据类型。
②通过typeof定义一个member指针类型的临时变量__mptr。
③将__mptr变量指向memberodga的指针变量ptr,这相当于创建了一个临时变量,防止后续操作改变了ptr。
2>(type *)( (char*)__mptr - offsetof(type, member) );
① (char*)__mptr,将指针变量类型转换成char*,offsetof(type, member)是结构体type中member成员变量相当于结构体首地址的偏移量
②(char*)__mptr - offsetof(type, member),用member的实际地址减去偏移量,得到type的起始地址
③将这个地址进行(type*)转换,得到了指向type类型的指针

list_entry

#define list_entry(ptr, type, member) container_of(ptr, type, member)

待补充。。。

list_for_each_entry

/*
 * 宏包含三个参数
 * --pos 
 * --head
 * --member
 */
#define list_for_each_entry(ptr, head, member) ({ \
		for (pos = list_entry((head)->next, typeof(*pos), (member)); \
		     &pos->member != (head); \
		     pos = list_entry(pos->member.next, typeof(*pos), (member)) )
})

待补充

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值