container_of 的用法及注意事项
来源:互联网 发布:螺纹钢库存数据9月9曰 编辑:程序博客网 时间:2024/04/30 11:40
container_of 的定义在 linux 内核 include/linux/kernel.h 中
/** * container_of - cast a member of a structure out to the containing structure * @ptr: the pointer to the member. * @type: the type of the container struct this is embedded in. * @member: the name of the member within the struct. * */#define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );})
其中的offsetof 的定义在 include/linux/stddef.h
#ifdef __compiler_offsetof#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)#else#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)#endif
在使用过程中一般不会有什么 问题,如:
typedef struct frame { int a; char b; char name[10];} frame_t;int main(int argc, char **argv){ frame_t fra, *pf; fra.a = 1; fra.b = 2; snprintf(fra.name, 5, "cjz%d", 1); pf = container_of(&fra.a, frame_t, a); printf("fra.a = %d, fra.b = %d, fra.name = %s\n", fra.a, fra.b, fra.name); return 0;}
但是下边的编译的时候就会有warning
typedef struct frame { int a; char b; char name[10];} frame_t;int main(int argc, char **argv){ frame_t fra, *pf; fra.a = 1; fra.b = 2; snprintf(fra.name, 5, "cjz%d", 1); pf = container_of(fra.name, frame_t, name); printf("fra.a = %d, fra.b = %d, fra.name = %s\n", fra.a, fra.b, fra.name); return 0;}编译过程:
gcc -c -o main.o main.cmain.c: In function ‘main’:main.c:29:57: warning: initialization from incompatible pointer type [enabled by default]gcc -Wall -I./ -o test main.o
注意红色部分,这是怎么回事呢?下面我们就来分析一下
container_of的部分展开
container_of(fra.name, frame_t, name) 展开如下 ({const typeof( ((frame_t *)0)->name ) *__mptr = (fra.name); \ (frame_t *)( (char *)__mptr - offsetof(frame_t, name) );})这样看来好像也没有什么 问题啊,但为什么 会有警告呢?因为typeof(数组名) ,这个我个先把它称为数组名类型,而typeof( ) 中要的是一个C中定义的类型,应该为数组元素类型,所以我们这里应该传数组首元素。pf = container_of(fra.name, frame_t, name[0]);注意红色部分与之前的不同,之前是name, 而这里是name[0]改后再编译gcc -c -o main.o main.cgcc -Wall -I./ -o test main.o警告就没有了
- container_of 的用法及注意事项
- container_of用法及实现
- linux container_of 的用法
- linux container_of 的用法
- sscanf 的用法 及注意事项
- SurfaceView的用法及注意事项
- container_of的含义及使用方法
- container_of用法
- 【原创】ComboBox的用法及注意事项
- 多线程CreateThread函数的用法及注意事项
- 多线程CreateThread函数的用法及注意事项
- Erlang“记录”的用法及注意事项
- 多线程CreateThread函数的用法及注意事项
- 多线程CreateThread函数的用法及注意事项
- 多线程CreateThread函数的用法及注意事项
- android imeOptions的用法及注意事项
- 多线程CreateThread函数的用法及注意事项
- 多线程CreateThread函数的用法及注意事项
- java_网页爬虫
- PowerDesigner之CDM、PDM、SQL之间转换
- 一维数组——菲波那契数列问题扩展
- TCP/IP 第21章 TCP超时和重传
- CKEditor+CKFinder+asp.net配置
- container_of 的用法及注意事项
- 通过一道面试题谈linux下的fork运行机制
- 地图配色及网络地图比较
- Linux下安装Jboss
- Ubuntu下可视化SVN
- Hibernate-Java-SQL 类型映射表 及Hibernate标识生成策略
- Linux静态库和动态库
- java web底层问题
- nginx 去掉服务器版本和名称和nginx_status 状态说明