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