先看一段代碼:
#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的類型和結構成員的類型不一致時會出一個警告,沒有的話就不會有警告了。
寫代碼時那兩個頭文件一定要包含,否則可能會編譯不通過。