关于Linux内核中container_of的思考
关于container_of中的实现原理这里不做任何的介绍说明,网上一搜一堆,这里只做一定的总结:
1)typeof,说白了能够将一个字符串翻译为一种类型类型进而定义该种类型的变量;
2)结构体中的成员变量相对于首地址的偏移是一定的,即首地址=0,成员变量的地址即为偏移
3)根据2)即可,若已知成员变量地址,即可获得结构体首地址
以前对这个成员变量的类型认识不到位,在内核中见的比较多的是,成员变量不是一个指针类型,只需要使用,指向该成员变量的指针进行地址操作即可;那如果这个成员变量是一个指针类型呢,我们操作的应该是指向这个成员变量(指针类型)的指针,也就是指针的指针,这在内核中很少见,但是这确实这个问题的本质,还是对指针类型理解不到位。
------------------2019/10/31更---------------------------
回头看之前写的,都不知道自己在说啥。。。
闲暇又对container_of实现了下,发现一个新问题:为什么container_of的实现中需要_mptr进行转换?直接将ptr转换成char*进行操作也能达到期望功能。
事实确实如此:直接对ptr进行操作,测试功能ok。翻了翻网上,第一句还真得写?能够在编译期间进行类型检查。如果ptr与&member类型不一致,会在编译期间报错。
#define my_offset_of(type, member) \
((size_t) &(((type*)0)->member))
#define container_of(ptr, type, member) ({ \
const decltype(((type*)0)->member)* _mptr = (ptr); \ //c++11,不允许用typeof
(type*)((char*)_mptr - my_offset_of(type, member));})