container_of(ptr, type, member)宏定义

linux内核数据结构中的链表实现可谓独树一帜。
普通的链表结构是在数据结构中嵌入链表指针

    struct fox{
        unsigned long tail_length;
        unsigned long weight;
        struct fox    *next;
        struct fox    *prev;
    }

而linux的实现则是将指针链表中嵌入数据结构

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

    struct fox{
        unsigned long tail_length;
        unsigned long weight;
        struct list_head list;
    }

使用宏container_of()可以取出链表指针父结构中包含的任何变量。

    #define container_of(ptr, type, member) ({
        const typeof(((type *)0)->member) *__mptr = (ptr);
        (type *)((char *)__mptr - offsetof(type, member));
    })
    /*
        typeof()构造了一个与ptr同类型的__mptr指针,并将ptr的值赋给了__mptr;
        然后用__mptr指针减去当前结构体成员在结构体中的偏移量即可。
    */

其中,ptr是指向当前结构体某一成员的指针,type是结构体名,member是ptr所指向的成员名。宏返回的是指向当前结构体类型起始地址的指针。
该宏定义中的offsetof()是另一个宏定义,可以求出结构体成员在结构体中的偏移值。

    #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
    /*
    &(((TYPE *)0)->MEMBER)取出了MEMBER相对于0地址的偏移值,然后用(size_t)转换了数据类型。
    */

这里我主要存留两个疑问,一是在constainer_of()宏中,为什么要申请新的__mptr指针,而不是直接用原来的ptr指针减去偏移值。二是为什么可以定义(TYPE *)0这样的指针。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值