[英]The (char *) casting in container_of() macro in linux kernel
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
我已经知道第一行是用于类型检查,但对于第二行,
为什么要进行(char *)
投射? 我找不到解释这个。
我自己做了一些实验代码,即使没有演员,结果似乎也很好。
它是为计算获取字节级地址。 否则,指针算法将根据所指向的类型进行,由于offsetof
以字节为单位计算偏移量,因此会中断。
转换为char *
在这样的低级基元内部非常常见,因为有时你真的需要将内存视为“字节数组”并在该级别操作它。
以此结构为例:
struct demo {
int foo;
float bar;
};
现在,如果我们这样做:
struct demo test;
float *intptr = &test.bar;
我们应该能够使用container_of()
获得指向test
的指针:
struct demo *owner = container_of(intptr, struct demo, bar);
这将扩展到:
struct demo *owner = {(
const typeof( ((struct demo*)0)->bar) *__mptr = (intptr);
(struct demo*)( (char *)__mptr - offsetof(struct demo,bar) );})
所以第一行声明了一个float
指针__mptr
并将参数值复制到它。
第二行将成员指针强制转换为char *
,然后在struct demo
减去bar
的偏移量(如果sizeof (int)
为4则为4),从而“备份”到整个结构test
的地址。
如果转换为char *
不存在,那么4
将被解释为float
(因为__mptr
是float *
),这显然会备份得太远(16个字节而不是4个,假设float
也是4个字节)造成可怕的破损。
请注意{(
包装扩展container_of()
语法是GCC扩展;这在标准C中不起作用。
有关container_of()
更多信息,请参阅此页面 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.