list_entry剖析与验证
来源:互联网 发布:淘宝的衣服能买吗 编辑:程序博客网 时间:2024/05/17 02:34
/*&((type *)0)->member: 把“0”强制转化为指针类型,则该指针一定指向“0”(数据段基址)。因为指针是“type *”型的,所以可取到以“0”为基地址的一个type型变量member域的地址。那么这个地址也就等于member域到结构体基地址的偏移字节数。 ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))): (char *)(ptr)使得指针的加减操作步长为一字节,(unsigned long)(&((type *)0)->member)等于ptr指向的member到该member所在结构体基地址的偏移字节数。二者一减便得出该结构体的地址,转换为 (type *)型的指针。 */#include <iostream>#include <typeinfo>using namespace std;struct list_head { struct list_head *next; struct list_head *prev;};#define list_entry(ptr, type, member)\ ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))struct test_list{ int testdata; float testfloat; struct list_head list;};int main(int argc, char *argv[]){ QCoreApplication a(argc, argv); struct test_list b; b.testdata = 5; b.testfloat = 11.2; struct test_list *pos = list_entry(&(b.testdata),struct test_list,testdata); cout << pos->testfloat << endl; return a.exec();}