引言
这段时间因为工作需要在研究开源工具Xdelta3的源码 ,发现了其中一个很有趣但不算常见的操作,先贴一下源码:
static inline xd3_rinst *xd3_rlist_entry(xd3_rlist *l)
{
return (xd3_rinst *)((char *)l - (ptrdiff_t) & ((xd3_rinst *)0)->link);
}
补充一下上面语句中出现的几个类型定义:
typedef unsigned char uint8_t;
typedef unsigned int usize_t;
typedef unsigned long long xoff_t;
typedef struct _xd3_rlist xd3_rlist;
typedef struct _xd3_rinst xd3_rinst;
struct _xd3_rlist
{
xd3_rlist *next;
xd3_rlist *prev;
};
struct _xd3_rinst
{
uint8_t type;
uint8_t xtra;
uint8_t code1;
uint8_t code2;
usize_t pos;
usize_t size;
xoff_t addr;
xd3_rlist link;
};
我先说明一下函数xd3_rinst *xd3_rlist_entry(xd3_rlist *l)
的作用,就是返回参数l
所属的xd3_rinst
类型结点的内存地址,其中包含type
xtra
...
等成员变量。
获取结构体中的某个变量的偏移量
我们知道,结构体类型中的成员变量是存储在内存中一段连续的内存地址上,我们所实例化的对象其实指向的是这段连续内存的首地址,也是结构体中第一个成员变量的内存地址,其他成员变量的取值都采用相对位置取址,也就是我们常说的偏移量取址,这和数组的取值是一个道理。