offsetof宏与container_of宏解析

offsetof宏的作用

用宏来计算结构体中某个元素和结构体首地址的偏移量(其实质是通过编译器来帮我们计算)。

container_of宏的作用

知道一个结构体中某个元素的指针,反推这个结构体变量的指针。有了container_of宏,我们可以从一个元素的指针得到整个结构体变量的指针,继而得到结构体中其他元素的指针。

offsetof宏的原理

我们虚拟一个type类型结构体变量,然后用type.member的方式来访问那个member元素,继而得到member相对于整个变量首地址的偏移量。

container_of宏的原理

先用typeof得到member元素的类型定义成一个指针,然后用这个指针减去该元素相对于整个结构体变量的偏移量(偏移量用offsetof宏得到的),减去之后得到的就是整个结构体变量的首地址了,再把这个地址强制类型转换为type *即可。

offsetof宏的分析

offsetof宏原型
TYPE为结构体类型 ;MEMBER为结构体中一个元素的元素名

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

(TYPE *)0 这是一个强制类型转换,把0地址强制类型转换成一个指针,这个指针指向一个TYPE类型的结构体变量。
((TYPE *)0)->MEMBER (TYPE *)0是一个TYPE类型结构体变量的指针,通过指针指针来访问这个结构体变量的member元素
&((TYPE *)0)->MEMBER 等效于&(((TYPE *)0)->MEMBER),意义就是得到member元素的地址。但是因为整个结构体变量的首地址是0,所以&(((TYPE *)0)->MEMBER)取出来的地址即为MEMBER的地址偏移量。

container_of宏的分析

container_of宏原型
ptr为指向结构体元素的指针;
type为结构体类型;
member为结构体中一个元素的元素名
这个宏返回的是指向整个结构体的指针,类型为(type*)

#define container_of(ptr, type, member) ({             /
         const typeof( ((type *)0)->member ) *__mptr = (ptr);     /
         (type *)( (char *)__mptr - offsetof(type,member) );})

宏原型分析
首先我们来看((type *)0)->member将0强制转换为type结构体类型的地址,然后从这个地址取出的member成员变量,得到member成员变量后使用typeof()就可以得到变量的类型也就是typeof( ((type *)0)->member )这一步,前面加的const是为了修饰使用typeof( ((type )0)->member )类型定义的指针变量__mptr不能去访问它,然后将传入指向member的成员的ptr指针赋值给_mptr,得到了指向member结构体成员变量的指针再减去有offsetof宏获得的成员变量在结构体中的偏移量,就可以得到结构体的起始地址,即为(type)型的结构体地址。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值