container_of宏实现如下:

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

首先,container_of的作用是,根据一个结构体变量中的一个域成员变量的指针来获取指向整个结构体变量的指针。

那么这里又涉及到 typeof 和 offsetof两个宏。

typeof 是用于得到变量的类型;typeof是GNU C对标准C的扩展。

offsetof 用于得到结构体中某个成员的内部偏移。

offsetof 的宏实现如下:

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

这里将0作为TYPE的起始地址,那么((TYPE *)0) ->MEMBER就是MEMEBER的地址,也就是偏移了。

offsetof和__builtin_offsetof实现相同。

有了typeof 和 offsetof 再来理解container_of 。第一行定义了一个 常量指针 __mptr, 指向的变量类型为member的类型, 值为ptr。

那么__mptr的地址减掉member的内部偏移就可以得到结构体的起始地址。

typeof, offsetof, container_of宏的更多相关文章

  1. linux中offsetof与container_of宏定义

    linux内核中offsetof与container_of的宏定义 #define offsetof(TYPE, MEMBER)    ((size_t) &((TYPE *)0)->M ...

  2. (转)offsetof与container_of宏[总结]

    1.前言 今天在看代码时,遇到offsetof和container_of两个宏,觉得很有意思,功能很强大.offsetof是用来判断结构体中成员的偏移位置,container_of宏用来根据成员的地址 ...

  3. offsetof与container_of宏[总结]

    1.前言 今天在看代码时,遇到offsetof和container_of两个宏,觉得很有意思,功能很强大.offsetof是用来判断结构体中成员的偏移位置,container_of宏用来根据成员的地址 ...

  4. offsetof与container_of宏分析

    offsetof宏:结构体成员相对结构体的偏移位置 container_of:根据结构体成员的地址来获取结构体的地址 offsetof 宏 原型: #define offsetof(TYPE, MEM ...

  5. offsetof宏与container_of宏

    offsetof宏与container_of宏1.由结构体指针进而访问各元素的原理(1)通过结构体整体变量来访问其中各个元素,本质上是通过指针方式来访问的,形式上是通过.的方式来访问的(这个时候其实是 ...

  6. 对offsetof、 container_of宏和结构体的理解

    offsetof 宏 #include<stdio.h> #define offsetoff(type, member)      ((int)&((type*)0)->me ...

  7. container_of宏定义分析---linux内核

    问题:如何通过结构中的某个变量获取结构本身的指针??? 关于container_of宏定义在[include/linux/kernel.h]中:/*_** container_of - cast a ...

  8. container_of宏剖析

    container_of宏剖析//该宏位于include/linux/kernel.h 1.定义格式 /** * container_of - cast a member of a structure ...

  9. 内核中container_of宏的详细分析【转】

    转自:http://blog.chinaunix.net/uid-30254565-id-5637597.html 内核中container_of宏的详细分析 16年2月28日09:00:37 内核中 ...

随机推荐

  1. Parse-轻松构建移动APP的后台服务

    目前正在开发的产品告一段落,有时间总结下经验,也顺便分享一下我们主要使用的平台-Parse. 什么是Parse?  Parse是一群美国人开发的专为移动APP服务的云计算平台,与现有的其他云计算平台相 ...

  2. P1934 封印

    P1934 封印 题目描述 很久以前,魔界大旱,水井全部干涸,温度也越来越高.为了拯救居民,夜叉族国王龙溟希望能打破神魔之井,进入人界“窃取”水灵珠,以修复大地水脉.可是六界之间皆有封印,神魔之井的封 ...

  3. HTTP协议基础篇(帮助理解)

    用uml 来描述一个功能是怎样按照时间的顺序完成的 实际的需求(配置网站/配置虚拟主机) 步骤 (1) 打开 apache/conf/httpd.conf 文件 (2)找到hosts文件 c:/win ...

  4. 第十八篇:java操作Excel要处理和分辨的几个概念

    工具:org.apache.poiExcel格式:.xls(03,存储量小些):.xlsx(07以上) 首先明确这点:给你一个装满数据的Excel,并不能保证每行都有数据,每一行并不能保证每个单元格都 ...

  5. 图解 5 种 Join 连接及实战案例!(inner/ left/ right/ full/ cross)

    Join 连接在日常开发用得比较多,但大家都搞清楚了它们的使用区别吗??一文带你上车~~ 内连接 inner join 内连接是基于连接谓词将俩张表(如A和B)的列组合到一起产生新的结果表,在表中存在 ...

  6. 获取调用U9接口时报错的方法

  7. Spring 事务传播行为(12)

    事务传播行为 指定是Spring中一个事务方法调用另一个事务方法时.处理的行为 使用方式: @Transactional(propagation=Propagation.REQUIRED) 事务的使用 ...

  8. 3.在vm上安装centos 7

    在vm上安装centos 7 1.文件 → 新建虚拟机 3.选择安装Linux系统 4. 虚拟机命名,并选择安装的文件夹 5.选择分配的处理器 6.使用网络地址转换 7.默写选项 9.新建虚拟机 10 ...

  9. 数据库DQL、DML、DDL及DCL详解

    目录 1. 数据查询语言(DQL,Data Query Language) 2. 数据操纵语言(DML,Data Manipulation Language) 3. 数据定义语言(DDL,Data D ...

  10. springboot启动过程

    使用了很长时间的springboot了,一直都知道它简单易用,简化了框架的搭建过程,但是还是不知道它是如何启动的,今天就跟着springboot的源码,去探探这其中的奥妙 以下是spring应用的启动 ...