2013-05-17 43 views
1

我期待在两个链表实现(queue.h [source]和utlist.h [source]),和我有一个关于他们各自实现了几个问题:一些链表C代码宏问题

  1. 什么是_Q_INVALIDATE所有关于queue.h?我想这是一些调试的一部分,但我不太了解宏define逻辑。
  2. 两种实现都提供FOREACHFOREACH_SAFE。前者是直截了当的,但第二个逻辑背后的逻辑是什么?另外,如果前者不安全,为什么它首先被执行?
  3. 为什么queue.hnextprevstruct *le_nextstruct **le_prev)的结构具有不同的类型?
  4. 在这两种实现中,为什么在这里和那里插入了额外的括号?例如。在#define LIST_FIRST(head) ((head)->lh_first)
+1

对于#4请参见:[在参数名称周围的宏中使用括号](https://www.securecoding.cert.org/confluence/display/seccode/PRE01-C.+Use+parentheses+within+macros+around +参数+姓名) –

+0

@MichaelBurr:啊,我现在明白了。谢谢。 – c00kiemonster

回答

4

周围head对于问题1:

_Q_INVALIDATE是设置不应再被用于的-1的值的指针的宏。意图是,如果它随后被使用,调试将变得更加容易,因为使用指针会导致立即崩溃。在非调试模式下,宏不做任何事情,所以指针保留其当前值 - 如果存在导致指针被使用的错误,则问题可能是一个更微妙的缺陷。

问题2:

这些宏的“安全”的版本采取宏观内部使用,而当前正在处理指向下一个项目列表中的一个额外的指针参数。这允许循环内的代码从列表中删除当前项目。由于下一个项目已经在temp指针中被记住了,所以这个宏在下一次迭代时没有问题。宏的非安全版本不使用临时指针,因此在迭代它时不能从列表中删除当前项目。

问题3:

这使得它更容易在当前一个之前添加新元素,或者从列表中删除当前元素没有关于当前元素是否在列表的头部关注(和因此只能由列表指针'指向')或当前元素是否位于列表中的其他位置(因此指向另一个元素的指针)。如果le_prevstruct type*,那么处理列表中的第一个元素将需要特殊的大小写代码。由于le_prevstruct type**,它可以像struct type*那样简单地引用struct type*(如列表头指针),该struct type*嵌入type(如每个元素中的le_next链接)内的某个任意偏移处。

问题4在上面的评论中得到了回答。

+0

棒极了。我并没有真正得到关于问题1的-1部分。非常聪明地指示不恰当地使用指针。非常感谢! – c00kiemonster