免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1346 | 回复: 7
打印 上一主题 下一主题

请教高手帮忙解释下这句话的意思,谢谢 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-03-13 14:59 |只看该作者 |倒序浏览
#define offsetof(__s_name, __s_member) (size_t)&(((__s_name *)0)->__s_member)

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
2 [报告]
发表于 2006-03-13 15:04 |只看该作者
给你两个选择:
1,从精华中找找,搜索关键字 offset
2,继续守株待兔。

论坛徽章:
0
3 [报告]
发表于 2006-03-13 16:03 |只看该作者

  1. #define offsetof(__s_name, __s_member) (size_t)&(((__s_name *)0)->__s_member)



  2. #include <stddef.h>

  3. #ifdef  _WIN64
  4. #define offsetof(s,m)   (size_t)( (ptrdiff_t)&(((s *)0)->m) )
  5. #else
  6. #define offsetof(s,m)   (size_t)&(((s *)0)->m)
  7. #endif
复制代码

__s_name是个结构,
__s_member是__s_name的成员。
offsetof的定义是取得成员__s_member的地址与结构__s_name的开始地址之间的偏移量。
假如:
__s_name的地址是:     0x12345600
__s_member的地址是:  0x123456FF

那么,offsetof之后的返回结果就是0xFF



令我不解的是以下语句:
((__s_name *)0)->__s_member


谁能解释一下?

[ 本帖最后由 westgarden 于 2006-3-13 18:54 编辑 ]

论坛徽章:
0
4 [报告]
发表于 2006-03-13 16:05 |只看该作者
原来出现过的问题。

返回结构NAME 中的项ITEM 相对结构开始的偏移位置。

论坛徽章:
0
5 [报告]
发表于 2006-03-13 17:01 |只看该作者
let p is a pointer to an object of type __s_name.
the address of __s_member in the object is
&p->__s_member = p + offset, so if p equals 0,
then offset = &0->__s_member.
In the equation above, type consistency is violated
(0 is int not ptr, &(0->__s_member) is of type ptr, rather than size_t),
so we must add type cast in order to pass compiler's type checking.
After type cast is added, the above equation is as following
offset = (size_t)&(((__s_name *)0)->__s_member).

conclusion: the macro computes the offset of an struct member, and
        should be mastered as an C idiom.

论坛徽章:
0
6 [报告]
发表于 2006-03-13 17:21 |只看该作者
原帖由 ovipgdft 于 2006-3-13 14:59 发表
#define offsetof(__s_name, __s_member) (size_t)&(((__s_name *)0)->__s_member)


这个实在太精典了,我是一辈子写不出这样的代码的,能看懂,我已经很高兴了.

论坛徽章:
0
7 [报告]
发表于 2006-03-13 17:27 |只看该作者
原帖由 aldebran 于 2006-3-13 17:01 发表
let p is a pointer to an object of type __s_name.
the address of __s_member in the object is
&p->__s_member = p + offset, so if p equals 0,
then offset = &0->__s_member.
In the  ...


谢谢!


转换成代码就是:

  1. #include <stdio.h>


  2. typedef struct X_t {
  3.         int a;
  4.         int b;
  5.         int c;
  6.         int x;
  7. }X;

  8. int main() {
  9.         int *p = 0;

  10.         ((X *)p)->x;
  11.         &(((X *)p)->x);
  12.         (size_t)&(((X *)p)->x);


  13.         ((X *)0)->x;
  14.         &(((X *)0)->x);
  15.         (size_t)&(((X *)0)->x);


  16.         return 0;
  17. }
复制代码

[ 本帖最后由 westgarden 于 2006-3-14 12:29 编辑 ]

论坛徽章:
0
8 [报告]
发表于 2006-03-13 21:59 |只看该作者
因为不直接引用数据成员,所以空指针在这里不具危险。同时,当结构的基址为 0 的时候,任意成员的偏移量就是直接取址得到的值。否则就需要一个更复杂的相减过程:

  1. #define offsetof(__s_name, __s_member, p) (size_t)(&(((__s_name *)p)->__s_member) - p )
复制代码


原来的宏相当于 p == 0 的情况。确实比较精巧。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP