Основа включения - убедиться, что ваши заголовки включены только один раз. Обычно это выполняется с такой последовательностью:
/* header.h */
#ifndef header_h_
#define header_h_
/* Your code here ... */
#endif /* header_h_ */
Второй момент - позаботиться о возможных конфликтах имен, обработав вручную псевдо-пространства имен с префиксами.
Затем вставьте в свои заголовки только объявления функций публичного API. Это может подразумевать добавление typedefs и перечислений. Старайтесь как можно больше включать объявления констант и переменных: предпочитайте функции доступа.
Другое правило - никогда не включать файлы .c, только .h. В этом и заключается смысл модульности: данному модулю, зависящему от другого модуля, нужно знать только его интерфейс, а не его реализацию.
A для вашей конкретной проблемы aStruct.h
использует struct smallerStruct
, но ничего не знает об этом, в частности, о его размере для возможности выделения переменной aStruct
. aStruct.h
должен включать smallerStruct.h
. Включение smallerStruct.h
до aStruct.h
в main.c
не решает проблему при компиляции aStruct.c
.