Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.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 宏的容器';s基准参考变更_C_Kernel_Linux Device Driver - Fatal编程技术网

C 宏的容器';s基准参考变更

C 宏的容器';s基准参考变更,c,kernel,linux-device-driver,C,Kernel,Linux Device Driver,让我们假设一个结构,当它的成员c的地址已知时,我们想要确定容器地址 struct some_data { char a; int b; char c; int d; }; 在container_of()宏中,在偏移量计算过程中,将基址更改为一个新的引用(0),然后针对该新的基址引用,按如下方式测量成员(例如c)的of集: long offset=(long)(&(struct some_data*)0)->c-0 这很好用。现在,根据更改基本引用的概念,以下内容也应该起作用:(我希望) lo

让我们假设一个结构,当它的成员c的地址已知时,我们想要确定容器地址

struct some_data {
char a;
int b;
char c;
int d;
}; 
在container_of()宏中,在偏移量计算过程中,将基址更改为一个新的引用(0),然后针对该新的基址引用,按如下方式测量成员(例如c)的of集:

long offset=(long)(&(struct some_data*)0)->c-0

这很好用。现在,根据更改基本引用的概念,以下内容也应该起作用:(我希望)

long offset=(long)(&(struct some_data*)100)->c-100


但事实证明,这是行不通的。您能帮我理解这里的错误吗。

我认为这段代码定义得不好。你应该使用标准的C
offset of
,而不是像这样的黑客。我尝试了问题中显示的代码,两个表达式都将
offset
设置为8,这在32位
int
与4字节边界对齐的系统上是有意义的。当然,如果将
->c
更改为
->b
->d
,它将不起作用。你说的“不起作用”是什么意思?虽然是UB,但GCC在这两种情况下都产生
8
的结果。参见
https://godbolt.org/z/sf8YhvGoM
。在我看来,展示UB是如何影响你的代码是有益的。@monzurulislam,你的例子是不相关的。
some_data::z
的类型是
int
。指针运算会出错。使用
some_data::y
在这两种情况下都会产生正确的结果。我认为您真正想要做的(处理大小大于1的成员)应该是
long offset=(long)和((struct some_data*)100)->c-100