2017-02-01 1 views
5

Je regardais les codes Glibc. Certains codes de la file d'attente de la glibc ont attiré mon attention. Je ne pouvais pas donner de sens à cette définition de structure. Cette structure n'a pas de nom. Pourquoi? Comment ça marche?c programmation #define struct {} déclaration

#define LIST_ENTRY(type)      \ 
struct {        \ 
    struct type *le_next; /* next element */   \ 
    struct type **le_prev; /* address of previous next element */ \ 
} 

Source

+1

Ressemble à un substitut à un modèle. – chris

+3

Dans de nombreux cas, les macros expriment un code * partial *. Regardez comment cette macro est * utilisée * plus tard dans le code pour voir la construction complète. Là, j'en suis sûr, vous verrez le nom manquant et tout ce qui est nécessaire. – AnT

+0

Notez que l'en-tête que vous avez référé dirige les gens vers [la page de manuel de 'queue' (3)] (http://man7.org/linux/man-pages/man3/queue.3.html) pour la documentation d'utilisation. Avez-vous lu cette page? Il donne en effet des explications, des instructions d'utilisation et un exemple de code pour cette macro et les autres dans ce fichier. –

Répondre

10

qui est en fait une macro préprocesseur, qui pourrait être élargi (très probablement avec le nom de fuite) ailleurs.

Dans les commentaires au début de ce fichier d'en-tête il y a une référence à queue(3) man page qui contient plus de détails à ce sujet et d'autres macros:

La macro LIST_ENTRY déclare une structure qui relie les éléments dans la liste .

Et un exemple d'utilisation:

LIST_HEAD(listhead, entry) head = LIST_HEAD_INITIALIZER(head); 
struct listhead *headp;     /* List head. */ 
struct entry { 
    ... 
    LIST_ENTRY(entry) entries;  /* List. */ 
    ... 
} 
*n1, *n2, *n3, *np, *np_temp; 

LIST_INIT(&head);      /* Initialize the list. */ 

n1 = malloc(sizeof(struct entry));  /* Insert at the head. */ 
LIST_INSERT_HEAD(&head, n1, entries); 

Être ce code C (pas C++), et C ne dispose pas de modèles, cette macro préprocesseur peut être utilisé pour les modèles "simuler" (note le paramètre type).

+0

Merci pour les commentaires, édité pour fournir un exemple meilleur et plus complet de l'utilisation. – roalz

+0

@ LightnessRacesinOrbit Mon commentaire n'a plus de sens après la modification de la question, donc je l'ai supprimé. – unwind

+0

@epoxxy Si cela vous a aidé, s'il vous plaît, acceptez la réponse en appuyant sur le signe de la coche près de celui-ci – roalz

8

C'est une macro qui est utilisée pour déclarer un type struct, avec next et prev des pointeurs vers des instances d'un second type struct. Ce second type peut être un type de parent, vous pouvez donc faire un « struct liable » comme ceci:

struct foo { 
    LIST_ENTRY(foo) list; 
    int value; 
}; 

Cela crée un struct foo contenant un membre appelé list qui à son tour est la structure en question, avec les pointeurs pointant à struct foo.

Nous pouvons maintenant créer une petite liste chaînée de struct foo s comme ceci:

struct foo fa, fb; 
fa.value = 47; 
fa.list.le_next = &fb; 
fa.list.le_prev = NULL; 
fb.value = 11; 
fb.list.le_next = NULL; 
fb.list.le_prev = &fa.list.le_next; 

Je ne suis pas sûr à 100% la dernière ligne, mais je pense qu'il sorte de logique.

+1

Puisque vous avez donné l'identifiant 'list' au membre de la liste dans' struct foo', vous devez utiliser 'fa.list.le_next' plutôt que' fa.le_next' (et de même pour 'le_prev'). Vous pouvez, cependant, rendre le membre de la liste anonyme en le déclarant comme 'LIST_ENTRY (foo);', et ensuite vous pouvez accéder à 'fa.le_next' et' fa.le_prev'. –

+0

@IanAbbott Merci! Fixe, bien sûr. OMG, ne sont pas des membres anonymes C11? :) – unwind

+0

Notez que sys/quque.h est également livré avec des macros pour ajouter/supprimer/etc.À partir d'une telle liste (documentée à l'adresse http://man7.org/linux/man-pages/man3/queue.3.html) – nos