這兩個巨集對於Linux核心原始程式碼非常的重要,它適用的範圍非常廣泛,被應用在Linked List與hash Table這一通用的資料結構中,用來化簡程式設計,並讓C語言也具備物件導向的行為,也是Linux物件導向中相當重要的機制!
size_t
: 表示一個byte的單位操作細節
(TYPE *)0
: 將 0
(數值意義上)轉型成 type
型別的指標&((TYPE *)0)->MEMBER
: 取得其成員記憶體位址編譯器處理
&((type *)0)->member
時,不會真正去存取地址為 0 的記憶體區段,只是將 0(數值意義上) 看做指標操作的一個運算元,除非額外有dereference操作。 https://hackmd.io/@sysprog/linux-macro-containerof
操作細節
__typeof__
取得 type
中 member
的資料型態,並且將 ptr
指派給 __pmember
__pmember
代表該 type
資料結構中成員的資料型態offsetof(type, member)
取得 member
在 type
中的offset(char *) __pmember
減去 offsetof(type, member)
即可得到結構體的起始位轉型成
char *
目的是確保地址操作是以 1 byte 為基準,由於char *
不論在哪裡都是1 byte(C語言標準),藉由這樣轉換方式能夠確保指標操作不會有問題
下面這張清楚地說明 container_of
的操作
可以透過contain_of
設計以下的物件導向的概念
在C語言上可以透過函數指標將方法綁定在特定資料結構上,所以C語言是需要透過一些語法或巨集來達成封裝的效果,雖然有語法的限制,但並不影響物件導向的精神
物件導向是一種態度,語法只是輔助
Jserv