Can someone explain 2 last lines of TAILQ_INSERT_TAIL macro:
#define TAILQ_INSERT_TAIL(head, elm, field) do {
(elm)->field.tqe_next = NULL; /
(elm)->field.tqe_prev = (head)->tqh_last; /
*(head)->tqh_last = (elm); /
(head)->tqh_last = &(elm)->field.tqe_next; /
} while (/*CONSTCOND*/0)
I understand, that, in generally, for insert in the tail of queue some node we need to do 4 things: 1) In node null pointer to next node. (first line of macro) 2) In last element of queue add pointer to node (second line of macro) 3) In node link pointer to previous node to last element in queue. 4) Update in queue head structure pointer to last element from last element in queue to our node.
1 and 2 points i understand clearly in macro, but 3 and 4 takes some misunderstanding, especially, i can not understand code like:
*(head)->tqh_last = (elm);
Call up last node in queue and overwrite it by current node? What will be with last node?
(head)->tqh_last is a pointer to another pointer, see here, the last line:
(head)->tqh_last = &(elm)->field.tqe_next;
so, if we exchange the last two lines, you can understand it
(head)->tqh_last = &(elm)->field.tqe_next;
*(head)->tqh_last = (elm);
refer <sys/queue.h>
/*
* Tail queue definitions.
*/
#define _TAILQ_HEAD(name, type, qual) \
struct name { \
qual type *tqh_first; /* first element */ \
qual type *qual *tqh_last; /* addr of last next element */ \
}
#define TAILQ_HEAD(name, type) _TAILQ_HEAD(name, struct type,)
#define TAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).tqh_first }
qual type *qual *tqh_last; it has two stars#define TAILQ_HEAD_INITIALIZER(head) { NULL, &(head).tqh_first }, it set thq_last to tqh_first's address, which is a pointer, so tqh_last is a pointer to pointerSee the similar question by Linus's answer(it's alot, just search At the opposite end of the spectrum in the page)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With