История вопроса:
В языке C иногда требуется, чтобы одна структура «знала» о другой, но при этом определение обеих структур зависит друг от друга (взаимная вложенность). Тогда невозможно определить одну структуру полностью перед объявлением второй. Для этого в C предусмотрено предобъявление (forward declaration) структур.
Проблема:
Без предобъявления компилятор не знает, что за тип встретился внутри структуры, и выдаст ошибку о неизвестном типе. Часто возникает ошибка, когда мы пытаемся сделать структуру, содержащую другую по значению, а не по указателю, или неверно пишем синтаксис.
Решение:
Forward declaration применяется, если нужно создать указатель на структуру, не раскрывая ее полное определение. Синтаксис — struct A;. Полное определение (struct A { ... };) можно дать позже.
Пример кода:
struct B; // forward declaration struct A { int val; struct B *link; }; struct B { int id; struct A *parent; };
Ключевые особенности:
Можно ли сделать поле типа "другая структура по значению" через forward declaration?
Нет, forward declaration разрешает использовать тип только в виде указателя, иначе будет ошибка: размер типа неизвестен.
struct B; // ok struct A { struct B b; // ошибка: размер B неизвестен };
Где правильно размещать forward declaration при работе с разными файлами?
Forward declaration размещают в заголовке, если структура используется только как указатель. Полное определение — либо в другом заголовке, либо в файле реализации.
Влияет ли forward declaration на размер структур и правильное выделение памяти?
Нет, потому что C не знает размера "неопределенной" структуры, а указатель всегда имеет одинаковый размер для данного компилятора, независимо от объявленного типа.
В заголовочном файле оба модуля содержали структуры с полями друг друга по значению. Сборка падала с ошибкой неопределённого типа.
Плюсы:
Минусы:
Один из программистов использовал forward declaration и указатели, минимизировав избыточные зависимости в заголовках. Компиляция и поддержка кода стала проще.
Плюсы:
Минусы: