Historia pytania:
W języku C czasami potrzebne jest, aby jedna struktura „znała” drugą, ale jednocześnie definicja obu struktur zależy od siebie (wzajemna złożoność). Wtedy nie można w pełni określić jednej struktury przed zadeklarowaniem drugiej. W tym celu w C przewidziano wstępne deklarowanie (forward declaration) struktur.
Problem:
Bez wstępnego deklarowania kompilator nie wie, jaki typ napotkał wewnątrz struktury, i zgłosi błąd o nieznanym typie. Często występuje błąd, gdy próbujemy stworzyć strukturę zawierającą inną w wartości, a nie wskaźniku, lub źle piszemy składnię.
Rozwiązanie:
Wstępne deklarowanie stosuje się, jeśli trzeba stworzyć wskaźnik na strukturę, nie ujawniając jej pełnej definicji. Składnia — struct A;. Pełną definicję (struct A { ... };) można podać później.
Przykład kodu:
struct B; // wstępna deklaracja struct A { int val; struct B *link; }; struct B { int id; struct A *parent; };
Kluczowe cechy:
Czy można stworzyć pole typu "inna struktura w wartości" przez wstępne deklarowanie?
Nie, wstępne deklarowanie pozwala używać typu tylko w postaci wskaźnika, w przeciwnym razie wystąpi błąd: rozmiar typu jest nieznany.
struct B; // ok struct A { struct B b; // błąd: rozmiar B jest nieznany };
Gdzie prawidłowo umieszczać wstępne deklaracje podczas pracy z różnymi plikami?
Wstępne deklaracje umieszczane są w nagłówku, jeśli struktura jest używana tylko jako wskaźnik. Pełna definicja — albo w innym nagłówku, albo w pliku realizacyjnym.
Czy wstępne deklarowanie wpływa na rozmiary struktur i prawidłowe przydzielanie pamięci?
Nie, ponieważ C nie zna rozmiaru „nieokreślonej” struktury, a wskaźnik zawsze ma ten sam rozmiar dla danego kompilatora, niezależnie od zadeklarowanego typu.
W pliku nagłówkowym oba moduły zawierały struktury z polami dotyczących siebie w wartości. Kompilacja zakończyła się błędem nieokreślonego typu.
Zalety:
Wady:
Jeden z programistów użył wstępnego deklarowania i wskaźników, minimalizując nadmiarowe zależności w nagłówkach. Kompilacja i konserwacja kodu stała się prostsza.
Zalety:
Wady: