先看一段代码:
#include <stdio.h> #include <stddef.h> #define container_of(ptr, type, member) ({ \ const typeof(((type *) 0)->member) *__mptr = (ptr); \ (type *) ((char *) __mptr - offsetof(type, member));}) #define container_of2(ptr, type, member) ({ \ (type *) ((char *) ptr - offsetof(type, member));}) typedef struct stTest stTest; struct stTest { char m1; int m2; char m3; int m4; char m5; int m6; }; int main(int argc,char *argv[]) { stTest st,*pst; char *p; printf("st= %p\n",&st); p = &(st.m3); printf("p = %p\n",p); pst = container_of(p,stTest,m3); printf("pst= %p\n",pst); pst = container_of2(p,stTest,m3); printf("pst2= %p\n",pst); return 1; }
可能输出如下:
[root@localhost ~]# ./test st= 0xbfef670c p = 0xbfef6714 pst= 0xbfef670c pst2= 0xbfef670c
它根据一个结构中一个成员的指针获得了整个结构的指针,不过宏中
const typeof(((type *) 0)->member) *__mptr = (ptr);
这句似乎可有可无。如果有的话,当指针p的类型和结构成员的类型不一致时会出一个警告,没有的话就不会有警告了。
写代码时那两个头文件一定要包含,否则可能会编译不通过。