请教一个宏的作用

发布于 2022-07-20 04:21:33 字数 1921 浏览 5 评论 6

问题稍有点复杂,怕描述不清楚:
有一个结构:
struct chain_head
{
        struct list_head list;
                ……
}A;

现在pos指向了A的list成员,如果已知了post的地址,要反过来求A的地址(不是用&A求地址,因为这是个链表……A的地址是不可知的,至于post指向了A的list成员,是通过其它手段实现的,)

实现这一功能的宏如下:
程序中调用:
struct chain_head *c = list_entry(pos, struct chain_head, list);
来获取。
原型:
/**
* list_entry - get the struct for this entry
* @ptr:        the &struct list_head pointer.
* @type:        the type of the struct this is embedded in.
* @member:        the name of the list_struct within the struct.
*/
#define list_entry(ptr, type, member)
        container_of(ptr, type, member)  

/**
* container_of - cast a member of a structure out to the containing structure
*
* @ptr:        the pointer to the member.
* @type:        the type of the container struct this is embedded in.
* @member:        the name of the member within the struct.
*
*/
#define container_of(ptr, type, member) ({                       
        const typeof( ((type *)0)->member ) *__mptr = (ptr);       
        (type *)( (char *)__mptr - offsetof(type,member) );})

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)不是很明白宏container_of的含义,盼指点……

[ 本帖最后由 独孤九贱 于 2006-3-26 13:01 编辑 ]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

清引 2022-07-22 11:53:29

原帖由 独孤九贱 于 2006-3-26 21:43 发表

刚才试了一下:
#include <stdio.h>

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

struct test
{
        int a;
        int b;
        int c;
};

main()
{
        printf("%Xn ...

自己来顶,开始没有仔细想,对于c,因为这是一个宏,编译器先展开替换,所以,当然能认到(结构)->c了,呵呵,弱智了,没有细想

另一个问题((TYPE *)0)->MEMBER)
A->member就是以A的地址为准开始算,0->member就是从NULL指针开始算。前面有一个&,所以,就是从NULL指针开始算的这个成员的偏移值了。
但是,NULL指针是个什么东东呢?它是从地址0开始的,CU上有篇精彩贴子:
http://www.chinaunix.net/jh/23/404711.html

[ 本帖最后由 独孤九贱 于 2006-3-27 21:50 编辑 ]

狼性发作 2022-07-22 11:53:14

原帖由 mq110 于 2006-3-26 15:22 发表
补充:
它不是什么类型.它就是你struct 结构里的struct list_head成员的名字.

刚才试了一下:
#include <stdio.h>

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

struct test
{
        int a;
        int b;
        int c;
};

main()
{
        printf("%Xn",(size_t) &((struct test *)0)->c);
        printf("%X",offsetof(struct test,c));
}
在VC6.0和gcc中都可以编译通过。

c真的可以直接写,不用事先像定义等诸如此类的,以前没有接触过这类用法,呵呵……又学习了,可是c既不是常量,也不是变量,编译器对于调用者中的c是如何处理的呢?

[ 本帖最后由 独孤九贱 于 2006-3-26 21:44 编辑 ]

九八野马 2022-07-22 11:50:35

补充:
它不是什么类型.它就是你struct 结构里的struct list_head成员的名字.

-梦醒时光 2022-07-22 11:49:43

第三个参数就是 你struct 结构里的struct list_head成员的名字。说起来很饶口.

比如

struct test
{
int a;
struct list_head list;
}

第3个参数就是list;

萌辣 2022-07-22 11:38:40

原帖由 mq110 于 2006-3-26 14:23 发表
看看这篇文章吧.

http://bbs.chinaunix.net/viewthr ... amp;highlight=mq110

list.h 这个头文件,好多Linux内核版本的书都提到过.~

非常感谢中……
然还有一个小疑问,在宏的调用者中,第三个参数(成员名)传递给宏,宏就可以直接利用其访问了,那么在调用者中,如上例中的list,它应该是一个什么类型呢?我用source insight没有跟到……

而且我觉得作者在讲offsetof这个关键部份还是有点模糊,因为它的作用跟据上下文可以很容易猜到,但是具体的实现还是有点不清不楚的

[ 本帖最后由 独孤九贱 于 2006-3-26 14:40 编辑 ]

北笙凉宸 2022-07-22 11:31:26

看看这篇文章吧.

http://bbs.chinaunix.net/viewthr ... amp;highlight=mq110

list.h 这个头文件,好多Linux内核版本的书都提到过.~

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文