关于container_of宏的疑问

辉hoi 2014-07-03 10:31:28
linux/kernel.h中的定义:
#define container_of(ptr, type, member) ({ \
const (typeof(((type *)0)->member) *)__mptr = ptr; \
(type *)(__mptr - offsetof(type, member)); \
})

为何不能定义成这样,而非要用一个局部变量来保存ptr,有什么好处?
#define container_of(ptr, type, member) ({ \
(type *)(ptr - offsetof(type, member)); \
})
...全文
173 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
辉hoi 2014-07-03
  • 打赏
  • 举报
回复
引用 4 楼 Intel0011 的回复:
const typeof( ((type *)0)->member ) *__mptr = (ptr); 这句话把三个参数都检查了,试想如果member是type结构体里的成员,但是member不是ptr所指的类型,换句话说ptr是正确的但是member是错误的,(type *)((char *)__mptr - offsetof(type, member)); 显然结果是错误的。但是 (type *)(ptr - offsetof(type, member));这句话编译器检查不出来,编译器不报错发出任何警告和错误
这个回答靠谱。有道理。 主要还是为了在编译阶段做检查及时发现错误。
Intel0011 2014-07-03
  • 打赏
  • 举报
回复
const typeof( ((type *)0)->member ) *__mptr = (ptr); 这句话把三个参数都检查了,试想如果member是type结构体里的成员,但是member不是ptr所指的类型,换句话说ptr是正确的但是member是错误的,(type *)((char *)__mptr - offsetof(type, member)); 显然结果是错误的。但是 (type *)(ptr - offsetof(type, member));这句话编译器检查不出来,编译器不报错发出任何警告和错误
赵4老师 2014-07-03
  • 打赏
  • 举报
回复
避免该宏的返回值被修改。我猜。
辉hoi 2014-07-03
  • 打赏
  • 举报
回复
引用 1 楼 mgy4938 的回复:
大哥,你这么改,连人家最初的定义都改了!container_of宏,主要作用是用于获得某结构中某成员的入口地址。 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) TYPE是某struct的类型 0是一个假想TYPE类型struct,MEMBER是该struct中的一个成员. 由于该struct的基地址为0, MEMBER的地址就是该成员相对与struct头地址的偏移量。 关于typeof,这是gcc的C语言扩展保留字,用于声明变量类型. const typeof( ((type *)0->member ) *__mptr = (ptr);意思是声明一个与member同一个类型的指针常量 *__mptr,并初始化为ptr. (type *)( (char *)__mptr - offsetof(type,member) );意思是__mptr的地址减去member在该struct中的偏移量得到的地址, 再转换成type型指针. 该指针就是member的入口地址了.
你没理解我问的什么意思。 这个宏的用途是获取包含member成员的结构体的基址。哪里是获取某成员的入口地址。
nextseconds 2014-07-03
  • 打赏
  • 举报
回复
大哥,你这么改,连人家最初的定义都改了!container_of宏,主要作用是用于获得某结构中某成员的入口地址。 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) TYPE是某struct的类型 0是一个假想TYPE类型struct,MEMBER是该struct中的一个成员. 由于该struct的基地址为0, MEMBER的地址就是该成员相对与struct头地址的偏移量。 关于typeof,这是gcc的C语言扩展保留字,用于声明变量类型. const typeof( ((type *)0->member ) *__mptr = (ptr);意思是声明一个与member同一个类型的指针常量 *__mptr,并初始化为ptr. (type *)( (char *)__mptr - offsetof(type,member) );意思是__mptr的地址减去member在该struct中的偏移量得到的地址, 再转换成type型指针. 该指针就是member的入口地址了.

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧