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宏的实现的更多相关文章

  1. 结构体指offsetof宏详细解析

    1.#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE*)0)->MEMBER)     (include/linux/stddef.h) ...

  2. C++类和对象(一)&&实现offsetof宏&&this指针

    一.目录 1.对象的相关知识 2.类的定义 3.类的实例化 4.类对象模型 5.模拟实现offsetof宏 6.this指针 二.正文 1.对象的相关知识 C语言是面向过程的,关注的是过程,分析求解问 ...

  3. offsetof宏与container_of宏

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

  4. Linux 内核预备知识:浅析 offsetof 宏以及新手的所思所想

    最近一头扎进了 Linux 内核的学习中,对于我这样一个没什么 C 语言基础的新生代 Java 农民工来说实在太痛苦了.Linux 内核的学习,需要的基础知识太多太多了:C 语言.汇编语言.数据结构与 ...

  5. container_of 和 offsetof 宏详解

    在linux内核链表中,会遇到两个宏. 在include/linux/stddef.h中,有这样的定义 #define offsetof(TYPE, MEMBER) ((size_t) &(( ...

  6. offsetof宏---个人笔记

    标准库里面提供的offsetof(t,m)宏,用来计算两个变量在内存中的地址偏移量 #include <stdio.h>//原型: #define offsetof(TYPE, MEMBE ...

  7. linux中offsetof与container_of宏定义

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

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

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

  9. offsetof与container_of宏[总结]

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

随机推荐

  1. Debian 7 源(32/64bit)好用的源

    deb http://mirrors.163.com/debian wheezy main non-free contrib deb http://mirrors.163.com/debian whe ...

  2. hive删除列

    hive中删除列时没有与mysql语句alter table <table> drop column <col>对应的语句. 然而依然可以完成此功能:使用ALTER TABLE ...

  3. [Android Pro] ListView,GridView之LayoutAnimation特殊动画的实现

    转载自:http://gundumw100.iteye.com/blog/1874545 LayoutAnimation干嘛用的?不知道的话网上搜一下. Android的Animation之Layou ...

  4. leetcoder-50-Pow(x, n)

    Pow(x, n) 能够直接用库函数pow(x,n)一步搞定,但明显这样就没意思了.   參考   快 速 幂 取 模 二分.复杂度为O(logn) 递归方法 class Solution { pub ...

  5. 【C#】:浅谈反射机制 【转】

    http://blog.csdn.net/lianjiangwei/article/details/47207875 什么是反射? 反射提供了封装程序集.模块和类型的对象(Type 类型).可以使用反 ...

  6. C#.net开发 List与DataTable相互转换 【转】

    http://blog.csdn.net/shuizhaoshui/article/details/51425527 在.NET开发中,操作关系型数据库提取数据经常用到DataTable.ASP.NE ...

  7. 阻止jQuery事件冒泡

    Query对DOM的事件触发具有冒泡特性.有时利用这一特性可以减少重复代码,但有时候我们又不希望事件冒泡.这个时候就要阻止 jQuery.Event冒泡. 在jQuery.Event 的文档 中的开头 ...

  8. RDD原理与详解

    RDD详解 原文连接 http://xiguada.org/spark_rdd/ RDD(Resilient Distributed Datasets弹性分布式数据集),是spark中最重要的概念,可 ...

  9. OceanBase支持索引查询啦!

    OceanBase支持索引后,上面的例子中用索引的查询速度是不用索引查询速度的40倍! 相关阅读 OceanBase简史 OceanBase Join操作 OceanBase内部表 OceanBase ...

  10. [转]mysql 常用命令集锦[绝对精华]

    测试环境:mysql 5.0.45 [注:可以在mysql中通过mysql> SELECT VERSION();来查看数据库版本] 一.连接MYSQL. 格式: mysql -h主机地址 -u用 ...