container_of函数原型

  • container_of(ptr,type,member) 该函数原理:已知结构体type的成员member的地址ptr,求结构体type的首地址。
1 #define offsetof(TYPE, MEMBER)  ((size_t) &((TYPE *)0)->MEMBER)
2 
3 #define  container_of(ptr, type, member) ({                            \
4            const typeof( ((type *) 0)->member)* __mptr = (ptr);      \
5            (type *)((char *)__mptr - offsetof(type, member));  })   

 函数实现由两部分:① 判断ptr 与 member的类型是否一致;② 计算起始地址。

  • container_of函数实现中第一行解释:(这行代码很巧妙)

  根据查找资料比较认可的说法:(1)检查三个参数,如果member是type的成员,但是ptr所指的类型不是member(也就是ptr是正确的,但是该ptr指向的不是member成员)那么计算出来的地址就是错误的;这种情况编译器不会报错和警告;(2)若开发者想赋值保存ptr,会在右边加上类型强转以免发生参数传输类型不符的情况。const typeof( ((type *) 0)->member)* __mptr = typeof( ( ((type *)0) -> member) *) (ptr); 内核禁止不规范的操作。详见关于container_of 第一行的__mptr作用的总结 - 内核源码-Chinaunix

  • 实现第二行的解释

  & ( ((type *) 0)->member )的作用是求出结构体起始地址到成员member的字节数大小,返回类型是size_t 无符号整型(否则内核会发出警告);这儿的0可以理解为被强制转换为 (type *)类型,它的作用就是指向该结构体起始地址的指针 ,从而求出相对地址的大小。接着利用(char *)__mptr :转化为char *是因为字节数减一就是减一(若为int型,则减一意味着字节数减四);再减去偏移地址,就是结构体的起始地址。

 

posted @ 2022-09-21 16:16  QianFa01  阅读(94)  评论(0)    收藏  举报