@time        2019-07-10
@author      Ruo_Xiao
@revision    linux  2.6.11

1、 offsetof

(1)原型

/** @member    TYPE    : 结构体原型。*            MEMBER  : 结构体成员。  */
#define offsetof(TYPE , MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

(2)文件路径:/ include / linux / stddef.h

(3)作用

返回指定类型(TYPE)的成员(MEMBER)在该结构体内的偏移量。

(4)解析

A、(TYPE *) 0

将以地址 0 为开始的,大小为 sizeof(TYPE) 的内存块按照 TYPE 进行看待。注意,这里只是看待,并没有进行读                取!这就保证了代码执行到这里并不会报错!

B、((TYPE *) 0) -> MEMBER

看看 MEMBER 成员,还是没有读取。

C、&(((TYPE *) 0) -> MEMBER)

看看 MEMBER 成员地址,还是没有读取。因为结构体的首地址为0,所以得到的 MEMBER 的首地址就是该成员相对            于结构体首地址的偏移量。

D、(size_t)&(((TYPE *)0) -> MEMBER)

将该地址转为 size_t 类型。

在32位系统中,size_t 的原型是 unsigned int 。

在64位系统中,size_t 的原型是 unsigned long 。

(5)栗子

#include <iostream>#define offsetof_t(TYPE , MEMBER) ((size_t)&(((TYPE *)0)->MEMBER))struct stest
{char    c;int     i;float   f;double  d;
};int main()
{int pos_c = offsetof_t(stest , c);int pos_i = offsetof_t(stest , i);int pos_f = offsetof_t(stest , f);int pos_d = offsetof_t(stest , d);std::cout << "stest::c 的偏移量:" << pos_c << std::endl;std::cout << "stest::i 的偏移量:" << pos_i << std::endl;std::cout << "stest::f 的偏移量:" << pos_f << std::endl;std::cout << "stest::d 的偏移量:" << pos_d << std::endl;return 0;
}

结果:

stest::c 的偏移量:0
stest::i 的偏移量:4
stest::f 的偏移量:8
stest::d 的偏移量:16

2、container_of

(1)原型

/** @member    ptr    结构体成员的地址。*            type   结构体原型。*            member 结构体成员。*/
#define container_of(ptr, type, member) ({          \const typeof( ((type *)0)->member ) *__mptr = (ptr);   \(type *)( (char *)__mptr - offsetof(type,member) );})

(2)文件路径:/ include / linux / kernel.h

(3)作用:通过结构体成员地址反推该结构体的地址。

(4)解析

A、typeof(  ( (type*)0 ) -> member ) )

获得 member 成员的数据类型。

B、const typeof(  ( (type*)0 ) -> member ) )  *_mptr = (ptr)

定义常量指针 _mptr,指向 ptr 指向的内容,该指针变量指向的内容是不可变的。

C、(char *)_mptr - offsetof(type , member)

前者将 _mptr 变为 字符指针,后者返回 member 在 type 的偏移量,二者相减就是 type 的首地址了。

最后在通过  (type *) 转为 type 型地址就可以了。

(5)栗子

#include <iostream>struct stest
{char    c;int     i;float   f;double  d;
};#define offsetof_t(TYPE , MEMBER) ((size_t)&(((TYPE *)0)->MEMBER))#define container_of_test(ptr , type , member) ({\const typeof(((type *)0)->member) *_mptr = ptr;\(type *)((char *)ptr - offsetof_t(type , member));})int main()
{stest test1;stest *p;p = container_of_test(&test1.i , stest , i);if (p == &test1){std::cout << "二者相同。" << std::endl;}else{std::cout << "二者不同。" << std::endl;}
}

结果:

二者相同

(SAW:Game Over!)

Linux / offsetof 和 container_of相关推荐

  1. linux中offsetof与container_of宏定义

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

  2. offset linux,Linux 宏定义之 offsetof 与 container_of(十九)

    今天我们来看看 Linux 中的两个经典的宏:offsetof 与 container_of.下来我们先来看看它们两个的宏定义,如下#ifndef offsetof #define offsetof( ...

  3. (六)linux内核中的offsetof与container_of宏

    参考: offsetof与container_of宏[总结] #define offsetof(type, member) (size_t)&(((type*)0)->member)#d ...

  4. linux 内核宏container_of剖析

    1.前面说的 我在好几年前读linux 驱动代码的时候看到这个宏,百度了好久,知道怎么用了,但是对实现过程和原理还是一知半解. container_of宏 在linux内核代码里面使用次数非常非常多, ...

  5. Linux内核中container_of宏的理解

    对 typeof 的理解: 实际上, typeof 并不是宏定义,它是GCC的关键字,是GCC特有的特性.如果只知道一个变量的名字要得到其类型,并不是宏定义能够完成的,这需要编译时的信息.所以,typ ...

  6. linux内核代码container_of

    它的作用显而易见,那就是根据一个结构体变量中的一个域成员变量的指针来获取指向整个结构体变量的指针. typedef unsigned int__kernel_size_t; typedef __ker ...

  7. Linux内核中的常用宏container_of其实很简单【转】

    转自:http://blog.csdn.net/npy_lp/article/details/7010752 开发平台:Ubuntu11.04 编 译器:gcc version 4.5.2 (Ubun ...

  8. Linux 内核链表剖析(二十)

    上节博客中,我们讲到了 Linux 中的宏定义 offsetof 与 container_of 宏.那么本节我们的课程目标就是一直 Linux 内核链表,使其适用于非 GNU 编译器,分析 Linux ...

  9. Linux结构体变量报错,23. Linux模式设计

    23.6. 结构体成员互访 由于内核中定义了很多复杂的数据结构,而它们的实例中的成员在作为函数参数传递的时,函数中可能需要对它的包含者中的其他的兄弟成员进行处理,这就需要只根据成员地址就可以获取整个结 ...

最新文章

  1. java好过去前一天日期_Java-日期保存为前一天
  2. python 如何用指数函数拟合数据?(2020年新型冠状病毒感染人数预测)
  3. 新年伊始 .Net7 preview1 发布!
  4. 项目管理十大知识领域,为何不含
  5. 第三章 正态性检验、自相关检验与异方差性检验
  6. 值得收藏的品牌案例—到集设,灵感即到
  7. HDU 3790 最短路径问题 (SPFA)
  8. 面试 AI 算法岗,项目实战与比赛经验到底能为你加成多少?
  9. CodeForces - 721E
  10. Xamarin.Forms 仿照京东搜索记录控件
  11. [礼仪大赛/模特比赛策划方案]现场场景描述
  12. 计算机组成白中英答案,计算机组成原理白中英答案
  13. 《HTTP权威指南》读书笔记(1)-HTTP简介与消息结构
  14. 软件包没有可安装候选
  15. 美团面试被问“红黑树”,我一脸懵逼......
  16. 大学计算机基础教程第13章数据库技术基础
  17. 互联网三大巨头依靠什么武器对垒O2O?
  18. (13)[ICLR16] Net2Net: ACCELERATING LEARNING VIA KNOWLEDGE TRANSFER
  19. 批量处理大量TXT格式的数据导入到数据库中
  20. 拼多多100亿的羊毛,就问你薅不薅?

热门文章

  1. C#:绘制Winform窗体
  2. Java Web整合开发(26) -- Spring概述
  3. tensorflow中的交叉熵损失
  4. Springboot整合swagger指南
  5. 前端JS通过Ajax下载后端返回的Excel文档
  6. synchronized(xxx.class)
  7. reactjs组件通讯:子组件传递数据给父组件
  8. 基于nginx实现minio分布式集群访问的负载均衡配置示例
  9. Django 3.2.5博客开发教程:体验django模板
  10. DEEPIN 20安装镜像进入LIVE模式