offsetof 详解
offsetof 宏
#define offsetof(s, m) (size_t)&(((s *)0)->m) |
ofssetof(s, m) 其中,s 是结构体名,m 是它的一个成员。s 和 m 同是宏 offsetof() 的形参,这个宏返回的是结构体 s 的成员 m 在结构体中的偏移地址。
(s *)0 : 这里的用法实际上是欺骗了编译器,使编译器认为 "0" 就是一个指向 s 结构体的指针(地址),还句话说 s 结构体就是位于 0x0 这个地址处。
(s *)0-> m : 自然就是指向这个结构体的 m 元素。
&((s *)0)->m : 表示 m 元素的地址。这里,如上面所说,因为编译器认为结构体 s 被认为是处于 0x0 地址处,所以 m 的地址自然的就是 m 在 s 中的偏移地址了。
最后将这个偏移值转化为 size_t 类型。
可能会感到迷惑,这样强制转换后的结构指针怎么可以用来访问结构体字段?呵呵,其实这个表达式根本没有也不打算访问m字段。ANSIC标准允许任何值为0的常量被强制转换成任何一种类型的指针,并且转换结果是一个NULL指针,因此((s*)0)的结果就是一个类型为s*的NULL指针。如果利用这个NULL指针来访问s的成员当然是非法的,但&(((s*)0)->m)的意图并非想存取s字段内容,而仅仅是计算当结构体实例的首址为((s*)0)时m字段的地址。聪明的编译器根本就不生成访问m的代码,而仅仅是根据s的内存布局和结构体实例首址在编译期计算这个(常量)地址,这样就完全避免了通过NULL指针访问内存的问题。又因为首址的值为0,所以这个地址的值就是字段相对于结构体基址的偏移。
size_t是针对系统定制的一种数据类型。它不是固定位数,在不同的系统里这个值都有可能不同( 它实际上是 unsigned int 类型 );而且在内存里,对于数据是高位对齐存储还是低位对齐存储各系统都不一样。所以,为了提高代码的可移植性,就有必要定议这样的数据类型。一般这种类型都会定义到它具体占几位内存等。当然,有些是编译器或系统已经给定义好的。具体要查看技手册。
欺骗编译器的#define offsetof(s,m) (size_t)&(((s *)0)->m)
#ifndef offsetof
#define offsetof(s,m) (size_t)&(((s *)0)->m)
#endif
offsetof 详解相关推荐
- 面试常考,项目易错,长文详解C/C++中的字节对齐
作者 | 李肖遥 来源 | 技术让梦想更伟大(ID:TechDreamer) 头图 | CSDN 下载自东方IC 引入主题,看代码 我们先来看看以下程序 //编译器:https://tool.lu/ ...
- Android init.rc文件解析过程详解(三)
Android init.rc文件解析过程详解(三) 三.相关结构体 1.listnode listnode结构体用于建立双向链表,这种结构广泛用于kernel代码中, android源代码中定义了l ...
- 位地址和字节地址换算_面试常考,项目易错,长文详解C/C++中的字节对齐
(给CPP开发者加星标,提升C/C++技能) 作者:技术让梦想更伟大 / 李肖遥 (本文来自作者投稿) 我们先来看看以下程序 //编译器:https://tool.lu/coderunner///来源 ...
- 转 C++宏定义详解
来自:传送门 C++宏定义详解 一.#define的基本用法 #define是C语言中提供的宏定义命令,其主要目的是为程序员在编程时提供一定的方便,并能在一定程度上提高程序的运行效率,但学生在学习时往 ...
- C语言中sizeof详解——面试C/C++
C面试sizeof详解 1.定义 sizeof是C语言的一种单目操作符,它并不是函数.sizeof操作符以字节形式给出了其操作数所占存储空间的大小.操作数可以是一个表达式或括在括号内的类型名.操作数所 ...
- C 和 C++ 宏 详解
From:https://www.cnblogs.com/njczy2010/p/5773061.html C中的预编译宏详解:http://www.cppblog.com/bellgrade/arc ...
- sizeof,strlen用法详解
sizeof 前向声明: sizeof,一个其貌不扬的家伙,引无数菜鸟竟折腰,小虾我当初也没少犯迷糊,秉着"辛苦我一个,幸福千万人"的伟大思想,我决定将其尽可能详细的总结一下. 但 ...
- container_of详解
container_of详解 #define container_of(ptr, type, member) ({ \ const typeof(((type ...
- 64位 int 占几个字节_面试常考,项目易错,长文详解C/C++中的字节对齐
面试常考,项目易错,长文详解C/C++中的字节对齐mp.weixin.qq.com 引入主题,看代码 我们先来看看以下程序 //编译器:https://tool.lu/coderunner/ //来 ...
最新文章
- HBM2E Flashbolt--提升人工智能的算力
- mongodb学习笔记6--杂项与补充
- 这个搞定系统监控的妙招,不来学可惜了
- Hibernate执行原理总结
- 马哥2016全新Linux+Python高端运维班第七周作业
- zsh 主题的下载和安装
- flash 火狐总是崩溃_win10系统火狐flash插件总是崩溃的解决方法
- CentOS7 下安装 Redis
- echarts中graphic_Echarts实现折线图
- php滑动门效果,JavaScript实现滑动门效果
- Java贪吃蛇(附完整代码下载链接)-跟随狂神一天完成
- Intelij的IDEA启动报错!parent directory is read-only or the user lacks necessary permissions
- ArcGIS地图制图教程——超详细
- “物联网×”:“互联网+”的下一个风口
- 【论文阅读】UAV-Based Crop and Weed Classification for Smart Farming
- 王者荣耀静态页面头部代码设计(2)
- dd命令 刻录U盘启动
- LNK1181:无法打开输入文件“release/.obj“
- 最小生成树 | Prim算法 Kruskal算法 |C语言
- 版本管理工具 git和SVN 忽略文件和目录
热门文章
- 专升本英语——语法知识——高频语法——第二节 谓语动词【学习笔记】
- Django搭建个人博客Blog-Day05
- excel求方差和标准差的函数_Excel标准差计算函数Stdev和StdevP的用法与区别,包含4个实例...
- windows10/11通过蓝牙传输文件
- DirectX(dll)修复软件推荐4.2增强版
- 各种安装包的下载地址
- 特殊符号: 和 | | 和 ?? 和 ?作用详解
- 痛惜!年仅43岁,又一位985高校博导因病逝世
- Crack:::Stimulsoft Ultimate 2023.1.2
- mapBox使用笔记