Uso de macros en C para definir estructuras de datos.

Estoy tratando de envolver mi cabeza en torno al concepto de usar macros para definir operaciones de estructura de datos. El siguiente código es un ejemplo simple para usar la biblioteca de listas incorporada en FreeBSD. En la biblioteca todas las operaciones se definen como macros. He visto este enfoque en un par de otras bibliotecas también.

Puedo ver que esto tiene algunas ventajas, por ejemplo. siendo la habilidad de usar cualquier estructura de datos como un elemento en la lista. Pero no entiendo muy bien cómo funciona esto. Por ejemplo:

  1. ¿Qué es stailhead ? Esto parece estar “justamente” definido.
  2. ¿Cómo pasar head y entries a una función?
  3. ¿Qué tipo es head , cómo puedo declarar un puntero a él?

¿Hay un nombre estándar para esta técnica que pueda usar para buscar en google o algún libro que explique este concepto? Cualquier enlace o buena explicación sobre cómo funciona esta técnica será muy apreciada.

Gracias a Niklas B. Corrí gcc -E y obtuve esta definición para head

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

y esto para stailq_entry

 struct stailq_entry { int value; struct { struct stailq_entry *stqe_next; } entries; }; 

Así que supongo que la head es de tipo struct stailhead .

 #include  #include  #include  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;ivalue = 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); } 

Primero lea esto para obtener una retención de lo que hacen estas macros. Y luego ir a la queue.h ¡Tendrás tu tesoro allí!

Encontré algunas monedas de oro para ti.

 #define STAILQ_HEAD(name, type) \ struct name { \ struct type *stqh_first;/* first element */ \ struct type **stqh_last;/* addr of last next element */ \ } 

Vamos a profundizar un poco y responder a tus preguntas.

¿Qué es stailhead? Esto parece estar “justamente” definido.

 #define STAILQ_HEAD(name, type) \ struct name { \ struct type *stqh_first;/* first element */ \ struct type **stqh_last;/* addr of last next element */ \ } STAILQ_HEAD(stailhead, entry) head = STAILQ_HEAD_INITIALIZER(head); struct stailhead *headp; /* Singly-linked tail queue head. */ 

Así que stailhead es una estructura.

¿Cómo pasar cabeza y entradas a una función?

 #define STAILQ_ENTRY(type) \ struct { \ struct type *stqe_next; /* next element */ \ } 

Por lo tanto, las entries y el head (como se explicó anteriormente) son solo estructuras y puede pasarlas al igual que pasa por otras estructuras. &structure_variable

¿Qué tipo es head, cómo puedo declarar un puntero a él?

¡Ya explicado!

Lee esta página de manual para ver bonitos ejemplos bonitos.