Linux內核編程:container_of解析
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
kernel中有很多地方會用到這個宏,這個宏的作用是根據結構體中某個成員變量的指針,獲取到該結構體的指針,而這個宏可以分成兩步來解析它:
將地址0強轉成type *指針,取到成員member指針,然後再使用typeof來獲取到member的類型,將結構體中變量ptr的指針保存到__mptr.
使用offsetof宏獲取到member變量相對於結構體type的偏移量,這樣將__mptr的值減去偏移量即是結構體的地址,然後再強轉即得到結構體指針。
從上面我們可以看到,不使用__mptr來保存ptr指針,直接用ptr指針來減偏移量不也可以達到目的麼?
答案是使用_mptr的目的是在編譯期間進行類型檢測(第一句,賦值時如果類型不匹配會報告警),保證傳入的成員地址與成員類型是匹配的,而在運行期間則和忽略中間變量__mptr是一樣的。
而關於offsetof宏的用法,相信看懂container_of這個宏後就可以很清晰的明白了。