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

kernel中有很多地方会用到这个宏,这个宏的作用是根据结构体中某个成员变量的指针,获取到该结构体的指针,而这个宏可以分成两步来解析它:

1. 将地址0强转成type *指针,取到成员member指针,然后再使用typeof来获取到member的类型,将结构体中变量ptr的指针保存到__mptr.

2. 使用offsetof宏获取到member变量相对于结构体type的偏移量,这样将__mptr的值减去偏移量即是结构体的地址,然后再强转即得到结构体指针。

从上面我们可以看到,不使用__mptr来保存ptr指针,直接用ptr指针来减偏移量不也可以达到目的么?

答案是使用_mptr的目的是在编译期间进行类型检测(第一句,赋值时如果类型不匹配会报告警),保证传入的成员地址与成员类型是匹配的,而在运行期间则和忽略中间变量__mptr是一样的。

而关于offsetof宏的用法,相信看懂container_of这个宏后就可以很清晰的明白了。

container_of宏解析 && 为什么需要使用中间变量__mptr?的更多相关文章

  1. container_of宏

    title: container_of宏 date: 2019/7/24 15:49:26 toc: true --- container_of宏 解析 在linux链表结构中有这样一个宏,通过成员变 ...

  2. container_of宏剖析

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

  3. linux中offsetof与container_of宏定义

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

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

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

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

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

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

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

  7. offsetof与container_of宏[总结]

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

  8. offsetof与container_of宏分析

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

  9. typeof, offsetof, container_of宏

    container_of宏实现如下: #define container_of(ptr, type, member) ({ \ )->member ) *__mptr = (ptr); \ (t ...

随机推荐

  1. 更新 | 2019年9月计算机二级office模拟题库

    随着2019年上半年计算机二级考试的完美落幕,紧接着的便是9月份的考试了. 到目前为止,下半年9月份计算机二级考试报名开通时间在6月前后,现在也基本结束. 2019年9月(56次)全国计算机等级考试( ...

  2. 2019-11-29-dotnet-core-输出调试信息到-DebugView-软件

    title author date CreateTime categories dotnet core 输出调试信息到 DebugView 软件 lindexi 2019-11-29 10:14:3 ...

  3. DigitalOcean 推荐的ubuntu16下LAMP安装过程

    LAMP安装过程: How To Install Linux, Apache, MySQL, PHP (LAMP) stack on Ubuntu 16.04 (另一个参考例程:Ubuntu 16.0 ...

  4. 【转】Linux iptables 详解

    转自:https://www.cnblogs.com/qwertwwwe/p/9452370.html 最近搭一个框架需要用到iptables做映射,学习了下iptables的原理,总结下方便以后查~ ...

  5. php字符串大小写转换

    strtoupper().strtolower().ucfirst().ucfirst().ucwords().mb_strtoupper().mb_strtolower()和mb_convert_c ...

  6. 二、Ubuntu16.04安装搜狗wps

    1.搜狗: 安装搜狗输入法,下载地址:http://pinyin.sogou.com/linux/(搜索官网下载及安装方法),deb安装方法类似Windows的exe安装,安装后重启生效. 2.wps ...

  7. QByteArray与QString的互相转换

    QByteArray baData; QString str = QString(baData); // 反过来转换: QByteArray by1 = str.toLatin1(); QByteAr ...

  8. python 反射、动态导入

    1. 反射 hasattr(obj,'name')            # 判断对象中是否含有字符串形式的方法名或属性名,返回True.False getattr(obj,'name',None)  ...

  9. JAVA语言程序设计-笔记摘录

    JAVA 程序语言设计(基础篇) 笔记摘录 为避免输入错误, 不要在nextByte().nextShort().nextInt()等等后面使用nextLine() nextXXXXX()都称为令牌读 ...

  10. 乐观锁和 MVCC 的区别?

    二者不是一个层面的东西. MVCC(Multi-Version Concurrent Control),基于快照隔离机制(Snapshot Isolations)进行多版本并发控制,是一种以乐观锁为理 ...