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();}