list.h中宏list_entry宏的解析与应用

list_enty这个宏算是内核里面比较复杂的宏了。下面就对它的结构进行解析。宏的结构为:

 

这个宏的作用是通过ptr指针获取type的地址,其中ptr是member的指针,member是type结构的成员。

这个宏里面包含另外一个宏,container_of。这个宏位于/linux/kerner.h,它的结构为:

 

这个宏包含两条语句。第一条:const typeof( ((type *)0)->member ) *__mptr = (ptr);首先将0转化成type类型的指针变量(这个指针变量的地址为0×0),然后再引用member成员(对应就是((type *)0)->member ))。注意这里的typeof(x),是返回x的数据类型,那么 typeof( ((type *)0)->member )其实就是返回member成员的数据类型。那么这条语句整体就是将__mptr强制转换成member成员的数据类型,再将ptr的赋给它(ptr本身就是指向member的指针)。第二条语句里面的offsetof也是一个宏,它在/linux/stddef.h中这样定义:

 

((TYPE *)0)->MEMBER)这个其实就是提取TYPE类型中的member成员,那么&((TYPE *)0)->MEMBER)得到member成员的地址,再强制转换成size_t类型(unsigned int)。因为它的结构体地址从0开始定义,所以得到的member成员的地址就是它相对于结构体的偏移地址。再回到contanier_of的第二句话,把得到的member的地址强制转化成char *,(这里不是很理解,借用别人的思路),因为如果member是非char型的变量,比如为int型,并且假设返回值为offset,那么这样直接减去偏移量,实际上__mptr会减去sizeof(int)*offset!这和指针的自加自减运算一样,根据其指向的变量的类型不同而不同。(同意)

接下来,container_of宏的含义就不言而喻了,也就是list_entry宏。

下面是对该宏实现的一个应用实例,以加深理解。

 

运行结果如下:

 

$ ./offset 

address of &stu is=0xbf89bb18

 

addressx of &stu-num=0xbf89bb18 offset of stu->num is=0

 

addressx of &stu-name=0xbf89bb1c offset of stu->name is=4

 

addressx of &stu-sex=0xbf89bb1d offset of stu->sex is=5

 

computing address of &stu using:

address and offset of stu->num=0xbf89bb14

address and offset of stu->name=0xbf89bb17

address and offset of stu->sex=0xbf89bb18

 

 

 

 

 

 

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值