在浏览Linux内核时,我发现了一个container_of宏,其定义如下:

#define container_of(ptr, type, member) ({                      \
        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
        (type *)( (char *)__mptr - offsetof(type,member) );})

我明白container_的作用,但我不明白的是最后一句话

(type *)( (char *)__mptr - offsetof(type,member) );})

如果我们按如下方式使用宏:

container_of(dev, struct wifi_device, dev);

最后一句的相应部分是:

(struct wifi_device *)( (char *)__mptr - offset(struct wifi_device, dev);

看起来什么都没做.

推荐答案

您的用法示例container_of(dev, struct wifi_device, dev);可能有点误导,因为您在那里混合了两个名称空间.

示例中的第一个dev指的是指针的名称,而第二个dev指的是 struct 成员的名称.

最有可能的是,这种混乱引起了所有人的头疼.实际上,您报价中的member参数指的是容器 struct 中为该成员指定的名称.

以这个容器为例:

struct container {
  int some_other_data;
  int this_data;
}

以及指向this_data成员的指针int *my_ptr,您可以使用宏通过以下方式获得指向struct container *my_container的指针:

struct container *my_container;
my_container = container_of(my_ptr, struct container, this_data);

this_data到 struct 开头的偏移量考虑在内对于获得正确的指针位置至关重要.

实际上,只需从指针my_ptr中减go 杆件this_data的偏移量即可得到正确的位置.

这正是宏的最后一行所做的.

C++相关问答推荐

执行自动聚焦规则后的CLIPS聚焦模块

C中空终止符后面的数字?

strftime函数中%s的历史意义是什么?为什么没有记录?

intellisense不工作,甚至已经下载了c/c++扩展

为什么STM32G474RE上没有启用RCC PLL

为什么GDB/MI进程的FIFO循环中有read()阻塞

如何在STM8项目中导入STM8S/A标准外设库(ST VisualDeveloper)?

用C语言计算文本文件中的整数个数

如何用c语言修改shadow文件hash部分(编程)?

如何只获取字符串的第一个单词,然后将其与c中的另一个单词进行比较?

C语言中浮点数的取整方式浮点数尾数超过23位时如何取整剩余部分

c程序,让用户输入两类数字,并给出输出用户输入多少个数字

即使我在C++中空闲,也肯定会丢失内存

在下面的C程序中,.Ap0是如何解释的?

发送和接收的消息中的Unix域套接字不匹配

当读取可能会阻塞管道中的父进程时,为什么要等待子进程?

std::malloc/calloc/realloc/free 与纯 C 的 malloc/calloc/realloc/free 有什么不同

为什么程序在打印每个数字之前要等待所有输入?

如何正确探测平台设备?

如何在 C 中的 Postgres 函数的表中 for 循环