欢迎光临散文网 会员登陆 & 注册

4.2 container_of的书写

2022-08-10 08:36 作者:Tokiyi  | 我要投稿

在对内核的理解上没有所谓的捷径,该花多少时间,该花多少精力,它就是应当要花到相当的程度才能产生理解。而且不应放过每一个细节,因为不能理解往往是一些细节没有做到极致。

近来我发觉到linux内核对container_of有两种不同的写法,有一种版本是这样写的:

#define container_of(ptr, type, member) ({              \         const typeof( ((type *)0)->member ) *__mptr = (ptr);    \         (type *)( (char *)__mptr - offsetof(type,member) );})

而另一种是这样写的:

#define container_of(ptr, type, member) ({                              \        void *__mptr = (void *)(ptr);                                   \        static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \                      __same_type(*(ptr), void),                        \                      "pointer type mismatch in container_of()");       \        ((type *)(__mptr - offsetof(type, member))); })

就实际效果而言,如果输入规范的话,两种书写算式事实上都能返回到被认为正确的结果。不过后一种还额外提供了一个检查参数输入是否得当的功能。

它是通过利用__same_type(type1,type2)结合static_assert(expr,msg)表达式,如果出现判断type1和type2类型不相同,则_same_type(type1,type2)等于0,这将导致static_assert(expr,msg)中的expr表示为0,那么在编译的阶段(还没到代码运行),编译器就会报出“Static error”并输出"msg"的信息。

在这里它要求ptr必须是member类型的指针,或者说ptr是一个空类型,否则就会校验出类型不匹配的错误信息:“pointer type mismatch in container_of()”

这给因使用container_of导致的错误提供了一个检测接口。


4.2 container_of的书写的评论 (共 条)

分享到微博请遵守国家法律