我是靠谱客的博主 醉熏眼神,最近开发中收集的这篇文章主要介绍剖析linux内核中的宏-----------offsetof,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

offsetof用于计算TYPE结构体中MEMBER成员的偏移位置。

#ifndef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif

 TYPE:结构体类型

MEMBER:结构体中的某一成员

分析:

1)(TYPE*)0:0被强制转换了,转换成了一个TYPE类型的结构体的指针

2)通过箭头操作,去访问MEMBER成员。问,在0地址处有个TYPE类型的结构体吗?答案肯定是没有的,因为0地址处是留给操作系统使用的。所以在0地址处绝对没有我们自定义的一个TYPE结构体变量。没有的话,这样写(TYPE *)0)->MEMBER,会不会引发程序的崩溃。现在就来讨论这个问题,要想弄明白这个问题,首先要了解编译器做了什么事情。

编译器做了什么?

编译器清楚地知道结构体成员变量的偏移位置;

通过结构体变量首地址与偏移量定位成员变量。

例如:

struct ST

{

  int i ;    //0

  int j;    //4

  char c; //8

}

struct ST s = {0};

struct ST *pst = &s;

int *pi = &(pst->i);  //(unsigned int )&s + 0  就是成员i的地址

int *pj = &(pst->j); //(unsigned int)&s + 4   就是成员j的地址

char *pc =&(pst->c) //(unsigned int)&s +8  就是成员c的地址

从上面可以看出,编译器根本没有真正访问pst所指向的地址中的内容,没有做任何的访问的工作。可以通过下面的成员进行验证:

如果我直接给它传一个空指针,程序会不会崩溃呢,看下面的代码:

从上面可以看出,程序不仅没有崩溃,反而把我们想要的结果打印出来,我们想要的结果就是结构体中的成员变量距离结构体首地址的偏移量。

利用offsetof这个结构体会不会实现同样的效果,继续看代码:

利用offsetof这个宏,成功的计算出了结构体中成员变量的偏移量。

总结:(TYPE *)0)->MEMBER  这个地方不会真正的去访问0地址处的内容,仅仅是编译器做了一个加法而已。用0+MEMBER在结构体中的偏移量,最后计算出一个地址。在此处该地址与MEMBER在结构体中的偏移量相等。

转载于:https://www.cnblogs.com/-glb/p/10344432.html

最后

以上就是醉熏眼神为你收集整理的剖析linux内核中的宏-----------offsetof的全部内容,希望文章能够帮你解决剖析linux内核中的宏-----------offsetof所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(30)

评论列表共有 0 条评论

立即
投稿
返回
顶部