Использование макросов в C для определения структур данных

Я пытаюсь обдумать концепцию использования макросов для определения операций со структурой данных. Следующий код представляет собой простой пример использования встроенной библиотеки списков в FreeBSD. В библиотеке все операции определены как макросы. Я видел этот подход также в нескольких других библиотеках.

Я вижу, что это имеет некоторые преимущества, например. способность использовать любую структуру данных в качестве элемента в списке. Но я не совсем понимаю, как это работает. Например:

What is stailhead? This seems to be "just" defined. How to pass head and entries to a function? What type is head, how can I declare a pointer to it?

Есть ли стандартное название для этой техники, которую я могу использовать для поиска в Google, или в любой книге, которая объясняет эту концепцию? Любые ссылки или хорошее объяснение того, как работает эта техника, будут высоко оценены.

БлагодаряНиклас Б. Я побежалgcc -E и получил это определение дляhead

<code>struct stailhead {
  struct stailq_entry *stqh_first;
  struct stailq_entry **stqh_last; 
} head = { ((void *)0), &(head).stqh_first };
</code>

и это дляstailq_entry

<code>struct stailq_entry {
 int value;
 struct { struct stailq_entry *stqe_next; } entries;
};
</code>

Так что я думаюhead имеет типstruct stailhead.

<code>#include <stdio.h>
#include <stdlib.h>
#include <sys/queue.h>

struct stailq_entry {
        int value;
        STAILQ_ENTRY(stailq_entry) entries;
};

int main(void)
{
        STAILQ_HEAD(stailhead, stailq_entry) head = STAILQ_HEAD_INITIALIZER(head);
        struct stailq_entry *n1;
        unsigned i;
        STAILQ_INIT(&head);                     /* Initialize the queue. */

        for (i=0;i<10;i++){
                n1 = malloc(sizeof(struct stailq_entry));   /* Insert at the head. */
                n1->value = i;
                STAILQ_INSERT_HEAD(&head, n1, entries);
        }
        n1 = NULL;

        while (!STAILQ_EMPTY(&head)) {
                n1 = STAILQ_LAST(&head, stailq_entry, entries);
                STAILQ_REMOVE(&head, n1, stailq_entry, entries);
                printf ("n2: %d\n", n1->value);
                free(n1);
        }

        return (0);
}
</code>

Ответы на вопрос(1)

Ваш ответ на вопрос