2012-04-06 5 views
2

Ich versuche, die inneren Funktionen von queue (3) Makros in Freebsd zu verstehen. Ich hatte eine vorherige question über das gleiche Thema gefragt, und das ist eine Follow-up-Frage dazu.Inkompatibler Zeigertyp - warum?

Ich versuche, eine Funktion zum Einfügen eines Elements in die Warteschlange zu definieren. queue (3) stellt das Makro STAILQ_INSERT_HEAD bereit, das einen Zeiger auf den Kopf der Warteschlange, den Typ der Elemente in der Warteschlange und das einzufügende Element benötigt. Mein Problem ist, dass ich

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

Störung erhalte, wenn ich versuche, die Adresse von head an die Funktion zu übergeben. Der vollständige Quellcode ist wie folgt:

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

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

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, entries); 
     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;i<10;i++){ 
       addelement(&head, i); 
     } 
     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); 
} 

Soweit ich das beurteilen kann, head ist vom Typ struct stailhead und die addelement Funktion erwartet auch einen Zeiger auf struct stailhead.

STAILQ_HEAD(stailhead, stailq_entry); expandiert nach:

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

Was ich hier fehlt?

Danke.

+1

Es kann etwas mit der Tatsache zu tun haben, dass Sie den STAILQ_HEAD-Makro zweimal aufrufen und so die Struktur neu definieren. Tu das nicht. Deklarieren Sie einfach head als eine Struktur des gewünschten Typs (d. H. "Struct stailhead head;"). Diese Makros sind nicht namespace-side-effect-free. – tbert

Antwort

2

Sie müssen nur die erste Zeile in der main Funktion von

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

zu

struct stailhead head = STAILQ_HEAD_INITIALIZER(head); 

konvertieren, was passiert, ist, dass STAILQ_HEAD ein Makro, das einen neuen Typ definiert, eine Struktur, die ist Ihre Datenstruktur mit dem Namen des ersten Parameters mit einem Eintragstyp des zweiten Parameters.

Sie sollten nur STAILQ_HEAD einmal anrufen, um den Typen der Struktur zu definieren - dann verwenden Sie diesen Typnamen von darauf neue Datenstrukturen dieser Art zu schaffen.

Was Sie in Ihrem Codebeispiel getan haben, ist einfach: Sie haben eine Struktur namens stailhead zweimal definiert - einmal im globalen Bereich und einmal im Rahmen Ihrer main-Funktion. Sie übergaben dann einen Zeiger auf das lokale stailhead an eine Funktion, die den globalen Typ mit demselben Name akzeptierte.

Obwohl beide Strukturen identisch sind, befinden sie sich in zwei verschiedenen Speicherbereichen, und der Compiler behandelt sie als unterschiedliche Typen. Es warnt Sie, dass Sie vom Typ main::stailhead in den Typ global::stailhead konvertieren (beachten Sie, dass ich gerade diese Notation erfunden habe, ich glaube nicht, dass es Kanon ist).

Sie müssen nur stailhead definieren, indem Sie das STAILQ_HEAD Makro nur einmal am Anfang der Datei aufrufen, wo Sie es bereits getan haben, und verwenden Sie struct stailhead, um ein Objekt dieses Typs zu definieren.

+0

Dies ist eine klare und prägnante Erklärung! Vielen Dank. – Raj

+0

Sie sind herzlich willkommen.Das Öffnen der Header-Datei und das Betrachten der Makrodefinitionen ist normalerweise eine gute Möglichkeit, um zu verstehen, was hinter den Kulissen passiert und Makro-Mysterien zu debuggen. –

Verwandte Themen