Geschichte der Frage:
In der Sprache C ist es manchmal erforderlich, dass eine Struktur von einer anderen "weiß", aber gleichzeitig hängt die Definition beider Strukturen voneinander ab (gegenseitige Verschachtelung). Dann ist es unmöglich, eine Struktur vollständig vor der Deklaration der anderen zu definieren. Daher sieht C die Vorabdeklaration (forward declaration) von Strukturen vor.
Problem:
Ohne Vorabdeklaration weiß der Compiler nicht, welcher Typ innerhalb der Struktur vorliegt, und gibt einen Fehler wegen unbekannten Typs aus. Häufig tritt ein Fehler auf, wenn wir versuchen, eine Struktur zu erstellen, die eine andere per Wert und nicht per Zeiger enthält, oder wenn wir die Syntax falsch schreiben.
Lösung:
Die Vorabdeklaration wird verwendet, wenn ein Zeiger auf eine Struktur erstellt werden soll, ohne die vollständige Definition preiszugeben. Die Syntax ist struct A;. Die vollständige Definition (struct A { ... };) kann später gegeben werden.
Beispielcode:
struct B; // Vorabdeklaration struct A { int val; struct B *link; }; struct B { int id; struct A *parent; };
Schlüsselmerkmale:
Kann man ein Feld vom Typ "andere Struktur per Wert" über Vorabdeklaration erstellen?
Nein, die Vorabdeklaration erlaubt die Verwendung des Typs nur als Zeiger, sonst tritt ein Fehler auf: Die Größe des Typs ist unbekannt.
struct B; // ok struct A { struct B b; // Fehler: Größe von B unbekannt };
Wo sollte die Vorabdeklaration beim Arbeiten mit verschiedenen Dateien richtig platziert werden?
Die Vorabdeklaration wird im Header platziert, wenn die Struktur nur als Zeiger verwendet wird. Die vollständige Definition sollte entweder in einem anderen Header oder in der Implementierungsdatei erfolgen.
Beeinflusst die Vorabdeklaration die Größe von Strukturen und die korrekte Speicherzuweisung?
Nein, da C die Größe von "undefinierten" Strukturen nicht kennt, und ein Zeiger immer die gleiche Größe für den gegebenen Compiler hat, unabhängig vom deklarierten Typ.
In der Header-Datei enthielten beide Module Strukturen mit Feldern von einander per Wert. Der Build schlug mit einem Fehler aufgrund eines undefinierten Typs fehl.
Vorteile:
Nachteile:
Einer der Programmierer verwendete Vorabdeklaration und Zeiger, um überflüssige Abhängigkeiten in den Headern zu minimieren. Die Kompilierung und Wartung des Codes wurden einfacher.
Vorteile:
Nachteile: