Hello, 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**).
If you insert a char dummy in between: #define TAILQ_ENTRY(type) \ struct { \ struct type *tqe_next; /* next element */ \ char dummy; \ struct type **tqe_prev; /* address of previous next element */ \ } then the test program below will crash: pref:afarber> cat tailq.c /* gcc -DQUEUE_MACRO_DEBUG tailq.c -o tailq */ #include <stdio.h> #include <sys/queue.h> typedef struct element { TAILQ_ENTRY(element) field; int i; } element; TAILQ_HEAD(headname, element) head = TAILQ_HEAD_INITIALIZER(head); int main(int argc, char* argv[]) { int i; element *pe; for (i = 0; i < 10; i++) { if ((pe = (element*) malloc(sizeof(*pe))) == NULL) err(1, NULL); pe->i = i; TAILQ_INSERT_TAIL(&head, pe, field); } printf("TAILQ_FOREACH:\n"); TAILQ_FOREACH(pe, &head, field) { printf("%d\n", pe->i); } printf("TAILQ_FOREACH_REVERSE:\n"); TAILQ_FOREACH_REVERSE(pe, &head, headname, field) { printf("%d\n", pe->i); } printf("TAILQ_LAST:\n"); pe = TAILQ_LAST(&head, headname); printf("%d\n", pe->i); return 0; } pref:afarber> gcc -DQUEUE_MACRO_DEBUG tailq.c -o tailq pref:afarber> ./tailq TAILQ_FOREACH: 0 1 2 3 4 5 6 7 8 9 TAILQ_FOREACH_REVERSE: Segmentation fault (core dumped) Also the TAILQ_LAST macro cheats by taking a (head)->tqh_last and saying that it's a pointer to the last element. But in fact it's a pointer to the tqe_next member of the last element. This works only because that member is the 1st one in that structure. IMHO a solution would be to change the head structure to hold just that: the pointer to the last element (which is needed above): #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... Am I wrong? Regards Alex -- http://preferans.de