Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 有人能给我解释一下容器中返回的类型吗?_C_Linux_Linux Kernel_Linux Device Driver - Fatal编程技术网

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)
,它将尝试获取文本的地址。