C++ offsetof
这是一个宏,用于计算类中某个成员的地址相对于类实例的偏移量
在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的更多相关文章
- linux中offsetof与container_of宏定义
linux内核中offsetof与container_of的宏定义 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->M ...
- 理解#define offsetof(struct_t,member) ((int)&((struct_t *)0)->member)
#define offsetof(struct_t,member) ((int)&((struct_t *)0)->member) 这个东西很多人应该知道: offsetof是用来判断结 ...
- 编程中的offsetof
linux和windows平台都已经定义了offsetof函数,用于取struct类型中某个变量的偏移量 在stddef.h头文件中,该宏的完整说明如下: #ifdef __cplusplus #if ...
- offsetof的使用
#include <stddef.h> #define offsetof ( TYPE, m) (size_t )&reinterpret_cast< const vol ...
- (转)offsetof与container_of宏[总结]
1.前言 今天在看代码时,遇到offsetof和container_of两个宏,觉得很有意思,功能很强大.offsetof是用来判断结构体中成员的偏移位置,container_of宏用来根据成员的地址 ...
- C语言typeof详解 offsetof
http://blog.chinaunix.net/uid-28458801-id-4200573.html 前言: typeof关键字是C语言中的一个新扩展,这个特性在linux内核中应用非常 ...
- typeof、offsetof、container_of的解释
链表是内核最经典的数据结构之一,说到链表就不得不提及内核最经典(没有之一)的宏container_of. container_of似乎就是为链表而生的,它的主要作用是根据一个结构体变量中的一个域成员变 ...
- #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)宏的运行机理:1. ( (TYPE *)0 ) 将零转型为TY ...
- C语言笔记(结构体与offsetof、container_of之前的关系)
关于结构体学习,需要了解:结构体的定义和使用.内存对齐.结构体指针.得到结构体元素的偏移量(offsetof宏实现) 一.复习结构体的基本定义和使用 typedef struct mystruct { ...
随机推荐
- IE7浏览器下CSS属性选择器二三事
一.为何专门说起IE7 以前,或者说数年前,我们从事桌面端网页开发的时候,基本上都还要兼顾IE6浏览器, 即使有些特性,IE7支持,我们也会忽略之.于是,我们会不自然地把IE6和IE7浏览器归为一路货 ...
- spring来了-02-HelloWorld
spring的各个版本说明: 在3.0以下的版本,源码有spring中相关的所有包[spring功能+依赖包],如:2.5版本 在3.0以上的版本,源码中只有spring的核心功能包[没有依赖包],如 ...
- JavaScript:闭包
根据MDN上的解释『闭包是指函数有自由独立的变量.换句话说,定义在闭包中的函数可以“记忆”它创建时候的环境.』 闭包有两个主要的作用: 1.访问内部函数的局域变量: 2.将创建的变量永久保存在内存中, ...
- js字符串函数之split()join()
split方法用于把一个字符串切割成字符串数组,与join相反 一个参数表示以该参数为切割点, var str="silence's world"; console.log(str ...
- 《Java程序设计》第三周学习总结
20145224-陈颢文 <Java程序设计>第三周学习总结 教材学习内容总结 一.定义类: ·类定义时使用class关键字,要对类中变量(值域成员/对象数据成员)行类型声明. class ...
- 自定义头文件 No such file or directory
my_file.h为你的头文件名 要用#include"my_file.h",而不能是#include<my_file.h>. 如果头文件名在尖括号<>里, ...
- UB单修改
FUNCTION Z_SD_UB_CHANGE. *"-------------------------------------------------------------------- ...
- Java List的深度克隆
关于java List的深度克隆 List是java容器中最常用的顺序存储数据结构之一.有些时候我们将一组数据取出放到一个List对象中,但是可能会很多处程序要读取他或者是修改他.尤其是并发处理的话, ...
- Hdu4349 Xiao Ming's Hope
Xiao Ming's Hope Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- DOM解析和SAX解析的区别
DOM解析和SAX解析的区别 博客分类: XML DOM SAX DOM解析和SAX解析的区别 No 区 别 DOM解析 SAX解析 1 操作 将所有文件读取到内存中形成DOM树,如果文件量过大,则 ...