offsetof宏和container_of宏

offsetof宏
用宏來計算結構體中某個元素和結構體首地址的偏移量(其實質是通過編譯器來幫我們計算)這個宏返回的是member元素相對於整個結構體變量的首地址的偏移量,類型是int。

#define offsetof(TYPE, MEMBER) ((int) &((TYPE *)0)->MEMBER)

(TYPE *)0 :
這是一個強制類型轉換,把0地址強制類型轉換成一個指針,這個指針指向一個TYPE類型的結構體變量。(實際上這個結構體變量可能不存在,但是隻要我們不去解引用這個指針就不會出錯)。

((TYPE *)0)->MEMBER:
(TYPE *)0是一個TYPE類型結構體變量的指針,通過指針來訪問這個結構體變量的member元素。

&((TYPE *)0)->MEMBER:
等效於&(((TYPE *)0)->MEMBER),意義就是得到member元素的地址。但是因爲整個結構體變量的首地址是0(相當於在0地址處虛擬構建了一個結構體變量指針)。

container_of宏
知道一個結構體中某個元素的指針,反推這個結構體變量的指針,繼而得到結構體中其他元素的指針。

#define container_of(ptr, type, member) ({
const typeof(((type *)0)->member) * __mptr = (ptr);
(type *)((char *)__mptr - offsetof(type, member)); })

ptr是指向結構體元素member的指針,type是結構體類型,member是結構體中一個元素的元素名。這個宏返回的就是指向整個結構體變量的指針,類型是(type *)。\爲連行符。這個宏的工作原理:先將用typeof關鍵字得到member元素的類型定義成一個指針,然後用這個指針減去該元素相對於整個結構體變量的偏移量(偏移量用offsetof宏得到的),減去之後得到的就是整個結構體變量的首地址了,再把這個地址強制類型轉換爲type *即可。

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