type de pointeur incompatible – pourquoi?

J’essaie de comprendre le fonctionnement interne des macros queue (3) dans Freebsd. J’avais déjà posé une question sur le même sujet et c’est une question complémentaire.

J’essaie de définir une fonction pour insérer un élément dans la queue. queue (3) fournit la macro STAILQ_INSERT_HEAD qui nécessite un pointeur sur l’en-tête de la queue, le type des éléments en queue et l’élément à insérer. Mon problème est que je reçois

 stailq.c:31: warning: passing argument 1 of 'addelement' from incompatible pointer type 

erreur lorsque j’essaie de passer l’adresse de head à la fonction. Le code source complet est le suivant:

 #include  #include  #include  struct stailq_entry { int value; STAILQ_ENTRY(stailq_entry) ensortinges; }; STAILQ_HEAD(stailhead, stailq_entry); int addelement(struct stailhead *h1, int e){ struct stailq_entry *n1; n1 = malloc(sizeof(struct stailq_entry)); n1->value = e; STAILQ_INSERT_HEAD(h1, n1, ensortinges); return (0); } 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); free(n1); } return (0); } 

Autant que je struct stailhead , head est de type struct stailhead et la fonction addelement attend également un pointeur pour struct stailhead .

STAILQ_HEAD(stailhead, stailq_entry); s’étend à:

 struct stailhead { struct stailq_entry *stqh_first; struct stailq_entry **stqh_last; }; 

Qu’est-ce que j’oublie ici?

Merci.

Il vous suffit de convertir la première ligne de votre fonction main partir de

 STAILQ_HEAD(stailhead, stailq_entry) head = STAILQ_HEAD_INITIALIZER(head); 

à

 struct stailhead head = STAILQ_HEAD_INITIALIZER(head); 

Ce qui se passe, c’est que STAILQ_HEAD est une macro qui définit un nouveau type, une structure qui correspond à votre structure de données avec le nom du premier paramètre avec le type d’entrée du second paramètre.

Vous n’êtes censé appeler STAILQ_HEAD qu’une STAILQ_HEAD fois pour définir le type de la structure. Vous utilisez ensuite ce nom de type pour créer de nouvelles structures de données de ce type.

Ce que vous avez fait dans votre exemple de code est simple: vous avez défini une structure appelée stailhead deux fois – une fois dans la scope globale et une fois dans la scope de votre fonction main . Vous stailhead alors un pointeur sur le stailhead local vers une fonction qui acceptait le type global avec le même nom.

Même si les deux structures sont identiques, elles se trouvent dans deux scopes de stockage différentes et le compilateur les traite comme des types distincts. Il vous avertit que vous passez du type main::stailhead au type global::stailhead (notez que je viens de composer cette notation, je ne crois pas que ce soit du canon).

Il vous suffit de définir stailhead en appelant la macro STAILQ_HEAD une seule fois en haut du fichier, et à partir de là, utilisez struct stailhead pour définir un object de ce type.