Linux内核中offsetof和container_of宏

1. 简介

No. 宏定义 作用 所属头文件
1 offsetof 获取结构体中成员的偏移位置 stddef.h
2 container_of 根据成员的地址来获取结构体的地址 linux/kernel.h

2. 宏定义offsetof

  • 示例:结构体struct foo中每个成员的偏移地址。
/* offsetof example */
#include <stdio.h>      /* printf */
#include <stddef.h>     /* offsetof */

struct foo {
  char a;
  char b[10];
  char c;
};

int main ()
{
  printf ("offsetof(struct foo,a) is %d\n",(int)offsetof(struct foo,a));
  printf ("offsetof(struct foo,b) is %d\n",(int)offsetof(struct foo,b));
  printf ("offsetof(struct foo,c) is %d\n",(int)offsetof(struct foo,c));
  return 0;
}
  • 源码
#define offsetof(type, member) (size_t)&(((type*)0)->member)
  • 解析
    将地址0强制转换为type类型的指针,member定位到结构体中偏移位置。编译器认为0是一个有效的地址,0type指针的起始地址。

3. 宏定义container_of

  • 示例:通过结构体struct foo中成员地址获取结构体地址。
/* container_of example */
#include <stdio.h>      /* printf */
#include <linux/kernel.h>     /* container_of */

struct foo {
  char a;
  char b[10];
  char c;
};

int main ()
{
  struct foo f;
  printf ("struct foo f is %p\n",&f);
  printf ("container_of(&(f.a),struct foo,a) is %p\n",container_of(&(f.a),struct foo,a));
  printf ("container_of(&(f.b),struct foo,b) is %p\n",container_of(&(f.b),struct foo,b));
  printf ("container_of(&(f.c),struct foo,c) is %p\n",container_of(&(f.c),struct foo,c));
  return 0;
}
  • 源码
#define container_of(ptr, type, member) ({ \
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
     (type *)( (char *)__mptr - offsetof(type,member) );}) 
  • 解析
  1. 首先定义一个临时的数据类型(通过typeof( ((type *)0)->member )获得)与ptr相同的指针变量__mptr,然后用它来保存ptr的值。
  2. (char *)__mptr减去member在结构体中的偏移量,得到的值就是整个结构体变量的首地址(整个宏的返回值就是这个首地址)。
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容