Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TAILQ_INSERT_TAIL macro <sys/queue.h>

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?

like image 277
Andriy Veres Avatar asked Mar 30 '26 21:03

Andriy Veres


1 Answers

(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);

Edit

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 }
  1. see qual type *qual *tqh_last; it has two stars
  2. see #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 pointer

Reference

See the similar question by Linus's answer(it's alot, just search At the opposite end of the spectrum in the page)

like image 68
大宝剑 Avatar answered Apr 02 '26 10:04

大宝剑