He visto definiciones completas de struct
s en encabezados y solo declaraciones. ¿Hay alguna ventaja de un método sobre el otro?
Si hace una diferencia, generalmente escribo def una estructura como esa en el .h
typedef struct s s_t;
Editar
Para ser claros, las opciones son declaración en el archivo de encabezado y definición en la clase, o tanto declaración como definición en el archivo de encabezado. Ambos deberían resultar en la misma usabilidad, incluso si uno es por enlace, ¿no es así?
Veo muchos casi duplicados, por ejemplo, aquí, pero sin coincidencias exactas. Por favor corríjame si me equivoco en este sentido.
_t
están reservados por POSIX, por lo que esto suele ser una mala idea. Podrías simplemente hacertypedef struct toto toto
._t
usos en otros lugares (por ejemplo, lighttp, linux) ... y prefijo cosas con projident_ entonces, eso no debería ser un problema, ¿verdad?C
ish, no (con elFILE
ejemplo, etc.). Entonces, no opaco.Respuestas:
Las estructuras privadas para ese archivo deben ir en el archivo .c, con una declaración en el archivo .h si son utilizadas por alguna función en .h.
Las estructuras públicas deben ir en el archivo .h.
fuente
global
ylocal
visibilidad?public
no tiene sentido en una estructura. Todas las estructuras son públicas de forma predeterminada.public
no es una palabra clave en C. Si observa la respuesta de Matthew Slattery a continuación, puede ver cómo usar solo una declaración directa en el encabezado causa un error del compilador cuando el usuario intenta usar miembros de un estructura privada (opaca).No, no cuando considera otros archivos .c que incluyen el mismo encabezado. Si la definición de la estructura no es visible para el compilador, los detalles de esa definición no se pueden utilizar. Una declaración sin una definición (por ejemplo, simplemente
struct s;
) hace que el compilador falle si algo intenta mirar dentrostruct s
, mientras que aún le permite, por ejemplo, compilarstruct s *foo;
(siempre quefoo
no se desreferencia más tarde).Compare estas versiones de
api.h
yapi.c
:Este cliente de la API funciona con cualquiera de las versiones:
Este hurga en los detalles de implementación:
que funcionará con la versión "definición en encabezado", pero no con la versión "definición en implementación", ya que en el último caso el compilador no tiene visibilidad del diseño de la estructura:
Por lo tanto, la versión de "definición en implementación" protege contra el uso indebido accidental o deliberado de detalles de implementación privados.
fuente
dereferencing pointer to incomplete type
fue exactamente mi caso!Si la estructura va a ser utilizada por otras unidades de compilación (archivos .c), colóquela en el archivo de encabezado para que pueda incluir ese archivo de encabezado donde sea necesario.
Si la estructura solo se usa en una unidad de compilación (archivo .c), colóquela en ese archivo .c.
fuente
El punto es que colocarlo en un archivo de encabezado le permite usar la estructura (o cualquier otra definición) de varios archivos de origen, con solo incluir ese archivo de encabezado.
Pero si está seguro de que solo se usará desde un archivo fuente, entonces realmente no hace ninguna diferencia.
fuente
Los puse en el archivo C para hacerlo más orientado a objetos, consulte este artículo .
fuente
Generalmente, no creo que haya una gran diferencia si los coloca en el encabezado o en los archivos fuente. Sin embargo, si necesita acceder a los miembros de una estructura desde varios archivos de origen, es más fácil colocar la estructura en un archivo de encabezado e incluirlo desde cualquier otro archivo donde se necesite la estructura.
fuente