日期:2014-05-16  浏览次数:20626 次

linux的链表设计问题
在linux内核中,有如何代码。请高手解释!
1.
#define   DBL_HLIST_FOR_EACH(pos,   head)   \
              for   (pos   =   (head)-> first;   pos   &&   ({   1;   });   \
                        pos   =   pos-> next)
#define   hlist_for_each_entry(tpos,   pos,   head,   member)                                         \
          for   (pos   =   (head)-> first;                                                                                 \
                    pos   &&   ({   1;})   &&                                             \
                                  ({   tpos   =   DBL_HLIST_ENTRY(pos,   typeof(*tpos),   member);   1;});   \
                    pos   =   pos-> next)

pos   &&   ({   1;   });   为什么要这么写啊,
pos   &&   ({   1;})   &&                                             \
                                  ({   tpos   =   DBL_HLIST_ENTRY(pos,   typeof(*tpos),   member);   呢

2.#define   container_of(ptr,   type,   member)   ({                                             \
              const   typeof(   ((type   *)0)-> member   )   *__mptr   =   (ptr);       \
              (type   *)(   (char   *)__mptr   -   offsetof(type,member)   );})
这个结构很典型,请高手解释一下!

------解决方案--------------------
1` pos && ({1;})是for循环结束的条件,意思是如果pos和{1;}做与操作不为0,即pos不为空。
由于Linux中链表的通用性,直接用pos != NULL在很多情况下是不合法的。
至于1为什么要加{},是为了适应结构体。
2` 这个是为了通过计算member的偏移量算出list中某元素的起始地址。
大概意思就是,宏定义这个表达式,先取得连接指针ptr的地址,因为struct的地址连续性,减去member的type大小,即sizeof(type),便可获得该结构的首地址。