offsetof宏的实现
1、c语言的结构体中,因为字节对齐的问题,导致成员地址并不能根据类型的大小进行计算。例如:
struct test {
char ch;
int a;
}
printf("test的大小=%d",sizeof(struct test)); //答案是8
/*注意下面第二个char *,必须是char型指针(和结构体第一个成员类型一致),
**因为你强制转换的是一个地址,所以必须用指针类型。
**另外一个地址只有有了类型才可以进行加减运算,否在地址+1不知道要移动几个字节。
*/
int *p=(int *)(char *)&test+; //错误,因为char并不是占用1个字节,而是4个字节
int *p=(int *)(char *)%test+; //正确
2、offsetof宏的实现如下:
#define offsetof(TYPE,MEMBER) (size_t) &((TYPE *)0)->MEMBER)
哈哈,复杂吧,解释一下:由于造成空洞的对齐动作是由编译器负责完成的,这里有一个欺骗编译器的指令:((TYPE *)0),
意思是定义一个指向TYPE类型的指针,且该指针值(也就是该type类型的地址)为0,当然这是不可能引用成功的,0地址早已
被操作系统保护起来了:),那么这么做意义何在?我们知道:当前地址-首地址=偏移量,如果首地址为0呢?当前地址是不是
就是偏移量了?呵呵,明白了吧,强制把0转换为type类型的指针,并不是为了访问0地址的值,而是为了从编译器里套话(假设首地址
为0时,当前地址是多少?)。
最后要注意:因为我们得到的是一个地址,所以要设置为size_t类型,如果设为int类型,编译器就要警告了,因为int和size_t的大小不相同。
最后以编译器的警告信息作为本文章的结尾吧:
warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
offsetof宏的实现的更多相关文章
- 结构体指offsetof宏详细解析
1.#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE*)0)->MEMBER) (include/linux/stddef.h) ...
- C++类和对象(一)&&实现offsetof宏&&this指针
一.目录 1.对象的相关知识 2.类的定义 3.类的实例化 4.类对象模型 5.模拟实现offsetof宏 6.this指针 二.正文 1.对象的相关知识 C语言是面向过程的,关注的是过程,分析求解问 ...
- offsetof宏与container_of宏
offsetof宏与container_of宏1.由结构体指针进而访问各元素的原理(1)通过结构体整体变量来访问其中各个元素,本质上是通过指针方式来访问的,形式上是通过.的方式来访问的(这个时候其实是 ...
- Linux 内核预备知识:浅析 offsetof 宏以及新手的所思所想
最近一头扎进了 Linux 内核的学习中,对于我这样一个没什么 C 语言基础的新生代 Java 农民工来说实在太痛苦了.Linux 内核的学习,需要的基础知识太多太多了:C 语言.汇编语言.数据结构与 ...
- container_of 和 offsetof 宏详解
在linux内核链表中,会遇到两个宏. 在include/linux/stddef.h中,有这样的定义 #define offsetof(TYPE, MEMBER) ((size_t) &(( ...
- offsetof宏---个人笔记
标准库里面提供的offsetof(t,m)宏,用来计算两个变量在内存中的地址偏移量 #include <stdio.h>//原型: #define offsetof(TYPE, MEMBE ...
- linux中offsetof与container_of宏定义
linux内核中offsetof与container_of的宏定义 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->M ...
- (转)offsetof与container_of宏[总结]
1.前言 今天在看代码时,遇到offsetof和container_of两个宏,觉得很有意思,功能很强大.offsetof是用来判断结构体中成员的偏移位置,container_of宏用来根据成员的地址 ...
- offsetof与container_of宏[总结]
1.前言 今天在看代码时,遇到offsetof和container_of两个宏,觉得很有意思,功能很强大.offsetof是用来判断结构体中成员的偏移位置,container_of宏用来根据成员的地址 ...
随机推荐
- [典型漏洞分享]Insert型SQL注入的发现和利用,篡改订单金额
本例中的SQL注入和其它发现的SQL注入的主要区别:1.生成订单接口是一次性的,反复提交无效,因此,此类型的SQL注入比较难通过扫描器发现,需要人工提取和手动测试.2.Insert类型的SQL注入,不 ...
- html在线美化网站
Html在线美化压缩/转js - 在线工具 地址:http://tool.lu/html/ 1.美化效果: 2.转化字符串拼接
- Excel 电子表格文件格式剖析
Excel 电子表格文件格式,这种Excel和其他的Excel是不同的.他的本质上是一个Xml文件(用英文版的UtraEdit可以看到),所以他可以保存任何符号的字符,包括&(它在Xml文件中 ...
- 在matlab中clear,clc,clf,hold作用介绍
clear 是清变量: clc 只清屏: clf 清除图形窗口上的旧图形: hold on 是为了显示多幅图像时,防止新的窗口替代旧的窗口: close 关闭所有显示的图像.
- SQL 的四种分类 DDL,DML,DCL,TCL
DDL (数据定义问题) 数据定义语言 - Data Definition Language 用来定义数据库的对象,如数据表.视图.索引等DDL不需要commit.CREATEALTERDROPTRU ...
- [转]Using the Microsoft Connector for Oracle by Attunity with SQL Server 2008 Integration Services
本文转自:http://technet.microsoft.com/en-us/library/ee470675(v=sql.100).aspx SQL Server Technical Articl ...
- 兄弟连新版Linux视频教程
兄弟连新版Linux视频教程目录:F:\linux\兄弟连新版Linux视频教程├(1)云计算是什么东西集群又是嘛玩意?.mp4├(2)兄弟连新版Linux教程 1.1.1 Linux系统简介-UNI ...
- Mount CIFS
mount -t cifs -o username="共享用户",password="密码" //ip/sharing_folder /mountpoint [ ...
- http://wsj356428476.iteye.com/blog/1655032
http://wsj356428476.iteye.com/blog/1655032 http://jingyan.baidu.com/article/19192ad83ce167e53e570705 ...
- C# http Post 方法
摘自: http://geekswithblogs.net/rakker/archive/2006/04/21/76044.aspx Http Post in C# Searched out on t ...