On 12/27/06, Alexander Farber <[EMAIL PROTECTED]> wrote:
the TAILQ_LAST and TAILQ_PREV macros in sys/queue.h only
work because by coincidence the head and the entry struct are
similar (they both have 2 pointers: struct type* and struct type**).

Umm, what makes you think that that is the result of coincidence and not design?


If you insert a char dummy in between:

...then you've broken the code by monkeying with something you
shouldn't.  That isn't a bug.


...
IMHO a solution would be to change the head structure to hold
just that: the pointer to the last element (which is needed above):

If you do that, TAILQ_INSERT_TAIL() would require an 'if', making it
slower.  I think the REMOVE macros would also need additional code to
handle when the last item is removed.  You would also need to a name
for the TAILQ_ENTRY() type to stand in for the headname you thought
you could drop.

In other words, it would be a substationally different structure.  You
can design such a thing and work out the details, but please don't
call it a "tail queue" or use the "TAILQ_" prefix, as that would just
result in confusion.


#define TAILQ_HEAD(name, type)                                          \
struct name {                                                           \
        struct type *tqh_first; /* first element */                     \
        struct type *tqh_last; /* addr of last element */         \
}

By fixing those 2 issues the headname argument of the 3 macros
TAILQ_LAST, TAILQ_PREV and TAILQ_FOREACH_REVERSE
could be dropped...

Something tells me that you haven't actually tried writing the altered
versions of those macros.  Just how were you expecting to get from a
pointer to an item's tqe_next member to the value of that item's
tqe_prev member?  *That's* what the cast lets you do.  Yes, it depends
on the head and entry structures having the exact same layout and
member types, but that's not in user-servicable code.


Philip Guenther

Reply via email to