linux内核中的container_of()宏中的(char *)转换
#define container_of(ptr,type,member) ({ const typeof( ((type *)0)->member ) *__mptr = (ptr); (type *)( (char *)__mptr - offsetof(type,member) );}) 我已经知道第一行是用于类型检查,但对于第二行, 解决方法
它是为计算获取字节级地址.否则,指针算法将根据所指向的类型进行,由于offsetof以字节为单位计算偏移量,因此会中断.
转换为char *在这样的低级基元内部非常常见,因为有时你真的需要将内存视为“字节数组”并在该级别操作它. 以此结构为例: struct demo { int foo; float bar; }; 现在,如果我们这样做: struct demo test; float *intptr = &test.bar; 我们应该能够使用container_of()获得指向测试的指针: 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) );}) 所以第一行声明了一个浮点指针__mptr并将参数值复制到它. 第二行将成员指针强制转换为char *,然后在struct demo中减去bar的偏移量(如果sizeof(int)为4则为4),从而“备份”到整个结构测试的地址. 如果转换为char *不存在,那么4将被解释为float(因为__mptr是float *),这显然会备份得太远(16个字节而不是4个,假设float也是4个字节)造成可怕的破损. 请注意{{包装扩展container_of()的语法是GCC扩展;这在标准C中不起作用. 有关container_of()的更多信息,请参阅this page. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |