offsetof(TYPE, MEMBER)和 container_of(ptr, type, member)

offsetof(TYPE, MEMBER)
該宏在Linux內核代碼(版本2.6.22)中定義如下:
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER);
 
分析:
(TYPE *)0,將 0 強制轉換爲 TYPE 型指針,記 p = (TYPE *)0,p是指向TYPE的指針,它的值是0。那麼 p->MEMBER 就是 MEMBER 這個元素了,而&(p->MEMBER)就是MENBER的地址,而基地址爲0,這樣就巧妙的轉化爲了TYPE中的偏移量。再把結果強制轉換爲size_t型的就OK了,size_t其實也就是int。
typedef __kernel_size_t  size_t;
typedef unsigned int __kernel_size_t;   
 
可見,該宏的作用就是求出MEMBER在TYPE中的偏移量。
#define container_of(ptr, type, member) ({                  /
    const typeof( ((type *)0)->member ) *__mptr = (ptr);    /
    (type *)( (char *)__mptr - offsetof(type,member) );})
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

          type
     |----------|
     |          |
     |          |
     |----------|
ptr->| member --|
     |----------|
     |          |
     |          |
     |----------|


1.ptr爲物理地址,其類型和member類型一致,最終使用typeof( ((type *)0)->member )
  由編譯器自動返回member的類型
2.type爲包含member成員的結構體
3.offsetof(type,member)爲member成員在type結構體中的偏移值,大小範圍0~sizeof(type)字節
 (因爲以0地址爲type類型數據結構的起始地址)
4.ptr- offsetof()就等於包含該ptr的type結構體父變量的物理起始地址,強制轉換爲(type*).


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章