list entry()巨集詳解

2021-07-23 17:04:10 字數 1305 閱讀 2599

#define list_entry(ptr, type, member) \

((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))

lish.h中定義

#define list_entry(ptr, type, member) /

container_of(ptr, type, member)

#define container_of(ptr, type, member)                 /

()#defineoffsetof(type, member) ((size_t) &((type *)0)->member)

linux不想用c++,但又想利用c++的優點,如是出現了很多奇怪的巨集,他們叫做trick。

ptr是找容器的那個變數的指標,把它減去自己在容器中的偏移量的值就應該 得到容器的指標。(容器就是包含自己的那個結構)。指標的加減要注意型別,用(char*)ptr是為了計算位元組偏移。((type *)0)->member是乙個小技巧。下面會解釋。前面的(type *)再轉回容器的型別

ptr是指向list_head型別鍊錶的指標,type為乙個結構,而member為結構type中的乙個域,型別為list_head,這個巨集返回指向type結構的指標。在核心**中大量引用了這個巨集,因此,搞清楚這個巨集的含義和用法非常重要。

設有如下結構體定義:

typedef struct ***

type;

定義變數:

type a;

type * b;

type1 * ptr;

執行:ptr=&(a.member);

b=list_entry(ptr,type,member);

則可使b指向a,得到了a的位址。

如何做到的呢?

先看&((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 *)型的指標,大功告成。

分析list entry()巨集

分析list entry 巨集 define list entry ptr,type,member type char ptr unsigned long type 0 member ptr是指向list head型別鍊錶的指標,type為乙個結構,而member為結構type中的乙個域,型別為li...

linux核心中的list entry巨集

初學linux核心 將學習中的一些知識點儲存起來,方便以後查閱。define list entry ptr,type,member container of ptr,type,member list entry只是一層封裝,實際上起作用的是container of巨集,define containe...

container of巨集詳解

該巨集位於include linux kernel.h 1.定義格式 define container of ptr,type,member 作用 就是根據乙個結構體變數中的乙個域成員變數的指標來獲取指向整個結構體變數的指標。例 struct demo struct struct demo stru...