关于offsetof宏函数的理解与探讨

[复制链接]
980|12
手机看帖
扫描二维码
随时随地手机跟帖
baimiaocun2015|  楼主 | 2017-12-18 23:40 | 显示全部楼层 |阅读模式
如题,,,我们在程序开发中会用到offsetof类似的函数来求某一成员的位置偏移量的,,这里经常见到,优势我们自己也会去亲自定义这个函数的。。那么,如下函数的,我们能怎么怎么去理解呢?
  offsetof 宏函数的定义——#define offsetof(struct_t,member) ((size_t)(char *)&((struct_t *)0)->member)
baimiaocun2015|  楼主 | 2017-12-18 23:43 | 显示全部楼层
这里,我们就一点一点的来理解的哈。。
(struct_t *)0是一个指向struct_t类型的指针,其指针值为 0,所以其作用就是把从地址 0 开始的存储空间映射为一个 struct_t 类型的对象。

使用特权

评论回复
baimiaocun2015|  楼主 | 2017-12-18 23:43 | 显示全部楼层
((struct_t *)0)->member 是访问类型中的成员 member,相应地 &((struct_t *)0)->member) 就是返回这个成员的地址。

使用特权

评论回复
baimiaocun2015|  楼主 | 2017-12-18 23:44 | 显示全部楼层
由于对象的起始地址为 0,所以成员的地址其实就是相对于对象首地址的成员的偏移地址。然后在通过类型转换,转换为 size_t 类型(size_t一般是无符号整数)。
所以,offsetoff(struct_t,member)宏的作用就是获得成员member在类型struct_t中的偏移量。

使用特权

评论回复
baimiaocun2015|  楼主 | 2017-12-18 23:45 | 显示全部楼层
个人认为其中的 (char *) 可以省略。。。

大家伙觉得呢?这里是要还是不要的?要了优势什么意思的呢?

使用特权

评论回复
baimiaocun2015|  楼主 | 2017-12-18 23:46 | 显示全部楼层
提供一个具体的实例的说明下
例如:
struct zhx{
int lanjuan;
};
这个结构体里的成员lanjuan,它的相对偏移量就是4;
这个宏里的0是地址,(s *)0,这一步是把从0这个地址开始的一块大小的内存解释成这个结构体类型,&(((s *)0)->m),这一步是取这个结构体程序m的地址,结合zhx这个结构体的例子,如果取成员lanjuan的地址,这个地址当然是4,对吧!也就是说,通过这个技巧,我们可以很方便的得到了这个成员偏移量。
size_t其实就是无符号整形,也就是把上面得到的那个地址转成无符号整形

使用特权

评论回复
zhangbo1985| | 2017-12-23 16:16 | 显示全部楼层
我弱弱的想问一下的,,我在程序中这样定义offsetof的宏,为何在pclint中检查不过的呢?

使用特权

评论回复
zhangbo1985| | 2017-12-23 16:18 | 显示全部楼层
这个定义的在iar的程序开发编译中是没有什么问题的,也是定义的对象的起始地址为 0。。。但就是pclint检查的不过

使用特权

评论回复
zhangbo1985| | 2017-12-23 16:37 | 显示全部楼层
后来定义的:
#define offsetof(struct_t,member) ((size_t)(char *)(&((struct_t *)0x10)->member)-(size_t)0x10),就可以了,也不影响编译结果的,,这个是为什么?

使用特权

评论回复
poijhgvfcd| | 2017-12-24 19:15 | 显示全部楼层
哦,这个还是不要用了吧

使用特权

评论回复
vivilzb1985| | 2017-12-24 22:37 | 显示全部楼层
baimiaocun2015 发表于 2017-12-18 23:43
这里,我们就一点一点的来理解的哈。。
(struct_t *)0是一个指向struct_t类型的指针,其指针值为 0,所以其 ...

这个是从0地址开始进行计算偏移量的

使用特权

评论回复
vivilzb1985| | 2017-12-24 22:38 | 显示全部楼层
zhangbo1985 发表于 2017-12-23 16:37
后来定义的:
#define offsetof(struct_t,member) ((size_t)(char *)(&((struct_t *)0x10)->member)-(size_ ...

这个((size_t)(char *)(&((struct_t *)0x10)->member)-(size_t)0x10)写法上是不是有问题的呢?

使用特权

评论回复
vivilzb1985| | 2017-12-24 22:51 | 显示全部楼层
是不是这样写就OK的。。。((size_t)(char *)(&(((struct_t *)0x10)->member)-(size_t)0x10)),,先是取menber的地址的,在减掉0x10的地址的

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

27

主题

1870

帖子

2

粉丝