这是一个宏,用于计算类中某个成员的地址相对于类实例的偏移量

在C++11中,要求这个类standard_layout

基本用法是这样子的:

#include <stdio.h>      /* printf */
#include <stddef.h> /* offsetof */ struct foo {
char a;
char b[];
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)); printf("%d\n", &(((struct foo*))->c)); return ;
}

注意除了用offsetof宏之外, printf("%d\n", &(((struct foo*)0)->c));也是一种办法

求取某个特定成员的偏移量的意义在哪儿呢?

linux内核中对于这一特性有一个绝佳的应用。内核数据结构中用到了很多的双向链表,进程描述符、页面描述符等等,它们各自被定义成不同

的结构体类型,但就双向链表这一数据结构而言,操作却是完全一致的,听起来该是c++模板大显身手的地方了。

于是就想到定义这样一种链表节点:

struct list_head
{
struct list_head *next, *prev;
};

需要使用双向链表的类型就会含有这样的成员,比如:

typedef struct page
{
struct list_head list;
.....
struct page *next_hash;
.....
struct list_head lru;
}mem_map_t;

这里面的成员(list或者lru)都会与其它page结构体中对应的链表节点成员相连,相当于成为一个连接件。

问题是我们要的是两个page结构之间相连,你弄成它们的成员相连,怎么用呢??

这就是offsetof大显身手的时候了,有了它,我们在知道成员地址之后,能求出page实例的基地址,从而

变相的实现了将两个page连接在一起的目的,同时复用了双链表这一基本数据结构。

C++ offsetof的更多相关文章

  1. linux中offsetof与container_of宏定义

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

  2. 理解#define offsetof(struct_t,member) ((int)&((struct_t *)0)->member)

    #define offsetof(struct_t,member) ((int)&((struct_t *)0)->member) 这个东西很多人应该知道: offsetof是用来判断结 ...

  3. 编程中的offsetof

    linux和windows平台都已经定义了offsetof函数,用于取struct类型中某个变量的偏移量 在stddef.h头文件中,该宏的完整说明如下: #ifdef __cplusplus #if ...

  4. offsetof的使用

    #include <stddef.h> #define offsetof ( TYPE, m)   (size_t )&reinterpret_cast< const vol ...

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

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

  6. C语言typeof详解 offsetof

    http://blog.chinaunix.net/uid-28458801-id-4200573.html 前言:    typeof关键字是C语言中的一个新扩展,这个特性在linux内核中应用非常 ...

  7. typeof、offsetof、container_of的解释

    链表是内核最经典的数据结构之一,说到链表就不得不提及内核最经典(没有之一)的宏container_of. container_of似乎就是为链表而生的,它的主要作用是根据一个结构体变量中的一个域成员变 ...

  8. #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

    #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)宏的运行机理:1. ( (TYPE *)0 ) 将零转型为TY ...

  9. C语言笔记(结构体与offsetof、container_of之前的关系)

    关于结构体学习,需要了解:结构体的定义和使用.内存对齐.结构体指针.得到结构体元素的偏移量(offsetof宏实现) 一.复习结构体的基本定义和使用 typedef struct mystruct { ...

随机推荐

  1. MyBatis执行过程显示SQL语句的log4j配置

    log4j.properties文件   log4j.rootLogger=debug,stdout,logfile log4j.appender.stdout=org.apache.log4j.Co ...

  2. iOS 中对 HTTPS 证书链的验证

    这篇文章是我一边学习证书验证一边记录的内容,稍微整理了下,共扯了三部分内容: HTTPS 简要原理: 数字证书的内容.生成及验证: iOS 上对证书链的验证. HTTPS 概要 HTTPS 是运行在 ...

  3. groovy基础

    字符串字面值 def age=25 log.info 'My age is ${age}' log.info "my age is \${age}" log.info " ...

  4. 采购订单限价(包含阶梯价)ME_PROCESS_PO_CUST

    为了能管控到钱财的每个环节,公司要求采购订单需要使用物料限价,当有报价低于先前的价格时,在采购订单保存时,更新最低限价 BADI:ME_PROCESS_PO_CUST process~item里做限价 ...

  5. oAuth协议学习

    我们的项目需要为一个认证网站开发一套API,这些API可以提供给很多公司来调用,但是公司在调用之前,必须先做授权认证,由此接触到了oAuth协议. 以下内容来自网络整理 定义 OAUTH协议为用户资源 ...

  6. 如何用SQL返回两个日期之间的所有连续日期

    在层次查询中,Oracle引入了一个伪列level,用来表示当前行(节点)对应的level, 它从1开始计数,每多一层level的值就加1. 我们可以据此实现对两个日期/整数之间所有日期/整数的遍历. ...

  7. 怎样打造一个分布式数据库——rocksDB, raft, mvcc,本质上是为了解决跨数据中心的复制

    摘自:http://www.infoq.com/cn/articles/how-to-build-a-distributed-database?utm_campaign=rightbar_v2& ...

  8. List<object> isEmpy contail 的判断

  9. 常用HTML转义字符,

    HTML字符实体(Character Entities),转义字符串(Escape Sequence) 为什么要用转义字符串? HTML中<,>,&等有特殊含义(<,> ...

  10. 使用AlarmManager定时更换壁纸----之二

    import java.io.IOException; import android.app.Service;import android.app.WallpaperManager;import an ...