offsetof與container of巨集解析

2021-08-28 21:45:17 字數 1375 閱讀 4738

1、前言

今天在看**時,遇到offsetof和container_of兩個巨集,覺得很有意思,功能很強大。offsetof是用來判斷結構體中成員的偏移位置,container_of巨集用來根據成員的位址來獲取結構體的位址。兩個巨集設計的很巧妙,值得學習。linux核心中有著兩個巨集的定義,並在鍊錶結構中得到應用。不得不提一下linux核心中的鍊錶,設計的如此之妙,只需要兩個指標就搞定了。後續認真研究一下這個鍊錶結構。

2、offsetof巨集

使用offsetof巨集需要包含stddef.h標頭檔案,例項可以參考:

offsetof巨集的定義如下:

#define offsetof(type, member) (size_t)&(((type*)0)->member)
巧妙之處在於將位址0強制轉換為type型別的指標,從而定位到member在結構體中偏移位置。編譯器認為0是乙個有效的位址,從而認為0是type指標的起始位址。

3、container_of巨集

使用container_of巨集需要包含linux/kernel.h標頭檔案,container_of巨集的定義如下所示:

#define container_of(ptr, type, member) ()
container_of巨集分為兩部分,

第一部分:const typeof( ((type *)0)->member ) *__mptr = (ptr);

通過typeof定義乙個member指標型別的指標變數__mptr,(即__mptr是指向member型別的指標),並將__mptr賦值為ptr。

第二部分: (type *)( (char *)__mptr - offsetof(type,member) ),通過offsetof巨集計算出member在type中的偏移,然後用member的實際位址__mptr減去偏移,得到type的起始位址,即指向type型別的指標。

第一部分的目的是為了將統一轉換為member型別指標。

4、測試程式

複製**

#include #include #define name_str_len  32

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

#define container_of(ptr, type, member) ()

typedef struct student_info

student_info;

int main()

測試結果:

5、參考**

container of與offsetof的原理

container of是linux核心中使用非常頻繁的乙個巨集,用於從包含在某個結構中的指標獲得結構本身的指標,通俗地講就是通過結構體變數中某個成員的首位址進而獲得整個結構體變數的首位址。define container of ptr,type,member 其中offsetof的定義 defin...

offsetof與container of巨集舉例

一 在linux kernel中關於offsetof與container of巨集的定義為 二 offsetof巨集介紹 b.offsetof巨集的原理 我們虛擬乙個type型別結構體變數,然後用type.member的方式來訪問那個member元素,繼而得到 member相對於整個變數首位址的偏移...

關於offsetof巨集

offsetof 巨集 這是在看書的時候遇到的,估計以後會用到,避免遺忘,先記下來吧。一般形式 define offsetof type,member size t type 0 member 說明 通過 type 0 將0位址強制轉換為type結構型別中的指標 通過 type 0 member 訪...