在linux 核心程式設計中,會經常見到乙個巨集函式container_of(ptr,type,member), 但是當你通過追蹤原始碼時,像我們這樣的一般人就會絕望了(這一堆都是什麼呀? 函式還可以這樣定義??? 怎麼還有0呢??? 哎,算了,還是放棄吧。。。)。 這就是核心大佬們厲害的地方,隨便兩行**就讓我們懷疑人生,凡是都需要乙個過程,慢慢來吧。
type的起始位址 = ptr - size (這裡需要都轉換為char *,因為它為單位位元組)。
到此,該函式已經講完,是不是很簡單??? 其實也不是,這裡並沒有提到size如何計算,而令我們頭暈的正是這裡。
好吧,先上container of函式原型:
#define container_of(ptr, type, member) ()
其次為 offserof 函式原型:
#define offsetof(type, member) ((size_t) &((type *)0)->member)
怎麼樣,是不是很炫? 好吧,下面開始揭開面紗:
(一)0 指標的使用 (自己給的名字,不知有木問題)
讓事實說話:
#include
struct test
;int main()
編譯執行,可以得到如下結果:
&temp = 0xbf9815b4
&temp.k = 0xbf9815bc
&((struct test *)0)->k = 8
什麼意思看到了吧,自定義的結構體有三個變數:i,j,k。 因為有位元組對齊要求,所以該結構體大小為4bytes * 3 =12 bytes. 而&((struct test *)0)->k 的作用就是求 k到結構體temp起始位址的位元組數大小(就是我們的size)。在這裡0被強制轉化為struct test *型, 它的作用就是作為指向該結構體起始位址的指標,就是作為指向該結構體起始位址的指標,就是作為指向該結構體起始位址的指標, 而&((struct test *)0)->k 的作用便是求k到該起始指標的位元組數。。。其實是求相對位址,起始位址為0,則&k的值便是size大小(注:列印時因為需要整型,所以有個int強轉)所以我們便可以求我們需要的 size 了 。 好吧,一不小心把 offsetof() 函式的功能給講完了:::
#define offsetof(type, member) ((size_t) &((type *)0)->member)
這次再看就順眼了吧(底層為什麼是這樣我還是不懂。。。只知道這樣確實可以) , 所以offsetof()的作用就是求我們夢寐以求的size, 並以size_t形式返回(size_t: 無符號整型)。
(二) 核心程式設計的嚴謹性
#define container_of(ptr, type, member) ()
這裡我們只看第二行:
const typeof( ((type *)0)->member ) *__mptr = (ptr);
它的作用是什麼呢? 其實沒什麼作用(勿噴勿噴,讓我把話說完),但就形式而言 _mptr = ptr, 那為什麼要要定義乙個一樣的變數呢??? 其實這正是核心人員的牛逼之處:如果開發者使用時輸入的引數有問題:ptr與member型別不匹配,編譯時便會有warnning, 但是如果去掉改行,那個就沒有了,而這個警告恰恰是必須的(防止出錯有不知道錯誤在**)。。。這嚴謹性可以吧
typeof( ((type *)0)->member )
它的作用是獲取member的型別僅此而已。至此基本結束
(三) 總結
container_of(ptr, type,member)函式的實現包括兩部分:
1. 判斷ptr 與 member 是否為同意型別
現在我們知道container_of()的作用就是通過乙個結構變數中乙個成員的位址找到這個結構體變數的首位址。
C語言巨集函式container of 簡介
在linux 核心程式設計中,會經常見到乙個巨集函式container of ptr,type,member 但是當你通過追蹤原始碼時,像我們這樣的一般人就會絕望了 這一堆都是什麼呀?函式還可以這樣定義?怎麼還有0呢?哎,算了,還是放棄吧。這就是核心大佬們厲害的地方,隨便兩行 就讓我們懷疑人生,凡是...
container of函式原理分析
container of cast a member of a structureout to the containing structure ptr the pointer to the member.指向成員變數的指標 type the type of the container struct...
關於container of函式分析
include define offset of type,member int type 0 member define container of ptr,type,member struct mytest intmain view code 一 分析下巨集定義1 define offset of...