C 有人能给我解释一下容器中返回的类型吗?
有人能给我解释一下这两个宏吗C 有人能给我解释一下容器中返回的类型吗?,c,linux,linux-kernel,linux-device-driver,C,Linux,Linux Kernel,Linux Device Driver,有人能给我解释一下这两个宏吗 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) #define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,memb
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
除了为什么偏移量为(size)和容器为(char*),我什么都懂
(char*)-(size_t)在这个宏中是如何工作的
我本以为他们俩是同一类型的。例如像char*。但是offsetof返回的值不是指针。顾名思义,它是给定对象中字段的偏移量。它是以字节为单位的。size\u t看起来是保存价值的绝佳类型 c中的指针算法很简单:p+n将p移动sizeof(*p)。例如,如果p指向一个大小为8的对象,p+1将其移动8,使其指向下一个对象
char的定义是1,因此char*指针上的所有指针算法都会移动1。因此,这里使用它来精确移动从offsetof获得的量。但是offsetof返回的值不是指针。顾名思义,它是给定对象中字段的偏移量。它是以字节为单位的。size\u t看起来是保存价值的绝佳类型 c中的指针算法很简单:p+n将p移动sizeof(*p)。例如,如果p指向一个大小为8的对象,p+1将其移动8,使其指向下一个对象
char的定义是1,因此char*指针上的所有指针算法都会移动1。因此,它在这里被用来精确地移动从offsetof获得的量。我不知道这怎么不会崩溃。但是
(char*)-size\u t'只是一个指针减量。当
p`是指针时,p-4
按4*sizeof(*p)
字节递减p
。我不知道这怎么不会崩溃。但是(char*)-size\u t'只是一个指针减量。当p`是指针时,p-4
按4*sizeof(*p)
字节递减p
。为什么不会崩溃?原因是因为它在宏中,并且null derefrence被优化掉了吗?您是指(type*)0)->成员位?这里没有尊重。typeof是获取类型的神奇编译器宏,(type*)0位只是获取成员的垃圾语法。是的。我指的是((TYPE*)0)->MEMBER
。如果我调用(offsetof(struct sockaddr,sa_family)
这不会将NULL
强制转换为struct sockaddr*
,然后在获取sa_family
的地址之前解除它的锁定吗?这就是我感到困惑的原因。那个是&((TYPE*)0)->成员。请注意符号-它不尊重任何内容,而是接受地址。地址是通过取指针的值(这里是0)并加上它来计算的。我想我不同意。由于优先级的原因,&
在->
之后应用。这就是它从0得到偏移量的方法。否则它将是&((TYPE*)0)
,它将尝试获取文本的地址。为什么不会崩溃?原因是因为它在宏中,并且null derefrence被优化掉了吗?您是指(type*)0)->成员位?这里没有尊重。typeof是获取类型的神奇编译器宏,(type*)0位只是获取成员的垃圾语法。是的。我指的是((TYPE*)0)->MEMBER
。如果我调用(offsetof(struct sockaddr,sa_family)
这不会将NULL
强制转换为struct sockaddr*
,然后在获取sa_family
的地址之前解除它的锁定吗?这就是我感到困惑的原因。那个是&((TYPE*)0)->成员。请注意符号-它不尊重任何内容,而是接受地址。地址是通过取指针的值(这里是0)并加上它来计算的。我想我不同意。由于优先级的原因,&
在->
之后应用。这就是它从0得到偏移量的方法。否则它将是&((TYPE*)0)
,它将尝试获取文本的地址。