2017-11-10 4 views
2

Ich habe in eine Codebasis von Drittanbietern gegraben und festgestellt, dass es anscheinend gültig ist, einen Typ als Zeiger auf eine undefinierte Struktur zu deklarieren. Als Mindestarbeits Beispiel eine C-Datei test.c enthält nichts betrachten, aber:Warum ist es zulässig, einen Typ als Zeiger auf eine undefinierte Struktur in C zu definieren?

typedef struct foo *bar;

Was mich wundert ist, dass diese Datei ohne Probleme kompiliert die mit dem Befehl

gcc test.c -shared

Warum Compiler nicht beschweren über die Struktur foo nicht irgendwo erklärt werden?

Meine Umgebung ist Ubuntu 16.04 mit gcc (Ubuntu 5.4.0-6ubuntu1 ~ 16.04.5) 5.4.0 20160609.

+0

Es ist nicht "undefined struct", es ist ein Zeiger auf unvollständigen Typ. –

Antwort

4

Die obige Deklaration erstellt eine Forward-Deklaration von struct foo. Obwohl Sie nicht auf seine Mitglieder zugreifen können, können Sie auf einen Zeiger darauf zugreifen.

Dies wird allgemein als undurchsichtiger Typ bezeichnet und wird verwendet, um Implementierungsdetails einer Bibliothek von Benutzern der Bibliothek zu verbergen.

Zum Beispiel eine Bibliothek Implementierung folgendes enthalten:

lib.c:

struct foo { 
    int f1; 
}; 

struct foo *init() 
{ 
    return malloc(sizeof(struct foo)); 
} 

void set1(struct foo *p, int val) 
{ 
    p->f1 = val; 
} 

int get1(struct foo *p) 
{ 
    return p->f1; 
} 

void cleanup(struct foo *p) 
{ 
    free(p); 
} 

Die Header-Datei für diese Bibliothek könnte wie folgt aussehen:

lib.h:

struct foo; 

struct foo *init(void); 
void set1(struct foo *p, int val); 
int get1(struct foo *p); 
void cleanup(struct foo *p); 

Der Benutzer dieser Bibliothek würde die Funktion init func verwenden um eine Instanz der Struktur und die set1 und get1 Funktionen zu erstellen, um das Element zu lesen/zu aktualisieren. Der Benutzer kann jedoch keine Instanz von struct foo erstellen oder auf die Mitglieder zugreifen, ohne eine der Schnittstellenfunktionen zu durchlaufen.

+0

Aber ja, das ist möglich, weil der Zeiger darauf gleich ist ... deshalb die Vorwärtsdeklaration und all das – coderredoc

+0

Ich denke, ich würde das tatsächlich umdrehen, @coderredoc. Die Tatsache, dass alle Zeiger auf Strukturtypen die gleiche Größe haben, folgt aus der Tatsache, dass C erlaubt, unvollständige Strukturtypen zu deklarieren (d. H. Mit einem Tag, aber ohne Körper) und Zeiger auf solche Typen abzuleiten. Der Effekt ist, dass die Größe der Strukturzeiger keine Funktion der Strukturelemente sein kann. –

+0

Ah nicht scheint es zirkulär .. @JohnBollinger: Viele Male habe ich hier die Rückseite gelesen.Ich denke, es gibt keinen gültigen Weg, um sicher zu wissen ... was fuhr, was – coderredoc

1

Da Zeiger auf structs gleiche Größe haben (für alle structs). Die Größe eines Strukturzeigers hängt nicht von seiner Definition ab. Denn egal wie, der Zeiger würde sich genauso verhalten wie jeder andere Strukturzeiger.

+0

Aber was ist mit Zeigerarithmetik? – linuxfan

+0

Ich vermisse sicherlich etwas ... wenn ich "Zeiger ++" schreibe, wenn Zeiger auf eine Vorwärtsdeklaration zeigt, wie viel der Zeiger inkrementiert wird? – linuxfan

+0

Ich habe einfach mehrere Möglichkeiten ausprobiert; Compiler beschwert sich mit "Fehler: Erhöhung des Zeigers auf unbekannte Struktur" und "Fehler: Arithmetik auf Zeiger auf einen unvollständigen Typ". – linuxfan

Verwandte Themen