Я видел как полные определения struct
s в заголовках, так и просто объявления - есть ли преимущества у одного метода перед другим?
Если это имеет значение, я обычно набираю такую структуру в .h
typedef struct s s_t;
редактировать
Для ясности, параметры - это объявление в файле заголовка и определение в классе или и объявление, и определение в файле заголовка. Оба должны приводить к одинаковому удобству использования, даже если одно связано с ним, не так ли?
Я вижу много почти дубликатов, например здесь, но нет точных совпадений. Пожалуйста, поправьте меня, если я ошибаюсь в этом плане.
_t
зарезервированы POSIX, так что это обычно плохая идея. Вы могли бы просто сделатьtypedef struct toto toto
._t
других мест (например, lighttp, linux) ... и я ставлю перед вещами префикс projident_, так что это не должно быть проблемой, не так ли?C
нет (как вFILE
примере и т. Д.). Итак, непрозрачный.Ответы:
Частные структуры для этого файла должны находиться в файле .c с объявлением в файле .h, если они используются какими-либо функциями в .h.
Публичные структуры должны быть в файле .h.
источник
global
иlocal
наглядность?public
не имеет смысла в структуре. По умолчанию все структуры общедоступны.public
не является ключевым словом в C. Если вы посмотрите на ответ Мэтью Слэттери ниже, вы увидите, как использование только прямого объявления в заголовке вызывает ошибку компилятора, когда пользователь пытается использовать члены частная (непрозрачная) структура.Нет, если рассматривать другие файлы .c с таким же заголовком. Если определение структуры не видно компилятору, детали этого определения использовать нельзя. Объявление без определения (например, просто
struct s;
) приводит к сбою компилятора, если что-то пытается заглянуть внутрьstruct s
, при этом позволяя ему, например, компилироватьstruct s *foo;
(до тех пор,foo
пока не будет разыменован позже).Сравните эти версии
api.h
иapi.c
:Этот клиент API работает с любой версией:
Вот он в деталях реализации:
который будет работать с версией «определение в заголовке», но не с версией «определение в реализации», поскольку в последнем случае компилятор не имеет видимости макета структуры:
Таким образом, версия «определение в реализации» защищает от случайного или преднамеренного неправильного использования частных деталей реализации.
источник
dereferencing pointer to incomplete type
был именно мой случай!Если структура должна использоваться другими единицами компиляции (файлы .c), поместите ее в файл заголовка, чтобы вы могли включить этот файл заголовка везде, где это необходимо.
Если структура используется только в одной единице компиляции (файл .c), вы помещаете ее в этот файл .c.
источник
Дело в том, что размещение его в файле заголовка позволяет вам использовать структуру (или любое другое определение) из нескольких исходных файлов, просто включив этот файл заголовка.
Но если вы уверены, что он будет использоваться только из одного исходного файла, тогда это не имеет никакого значения.
источник
Я поместил их в файл C, чтобы сделать его более объектно-ориентированным, см. Эту статью .
источник
В общем, я не думаю, что это имеет большое значение, помещаете ли вы их в заголовочные или исходные файлы. Однако, если вам нужно получить доступ к элементам структуры из нескольких исходных файлов, проще поместить структуру в файл заголовка и включить ее из любых других файлов, где структура необходима.
источник