funciones - ¿Deberían ir las definiciones de estructuras en el archivo.h o.c?
estructuras en c pdf (6)
He visto definiciones completas de struct
s en encabezados y declaraciones justas: ¿hay alguna ventaja para un método sobre el otro?
Si hace una diferencia, usualmente escribo una estructura como en el .h
typedef struct s s_t;
Editar
Para que quede claro, las opciones son declaración en el archivo de encabezado y definición en la clase, o declaración y definición en el archivo de encabezado. Ambos deberían dar como resultado la misma usabilidad, incluso si uno es por vinculación, ¿no es así?
Veo muchos casi duplicados, por ejemplo here pero sin coincidencias exactas. Por favor corrígeme si me equivoco al respecto.
Ambos deberían dar como resultado la misma usabilidad, incluso si uno es por vinculación, ¿no es así?
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 usar. Una declaración sin una definición (p. Ej., Simplemente struct s;
) hace que el compilador falle si algo trata de buscar dentro de struct s
, al mismo tiempo que le permite, por ejemplo, compilar struct s *foo;
(siempre que foo
no sea luego desreferenciado).
Compare estas versiones de api.h
y api.c
:
Definition in header: Definition in implementation:
+---------------------------------+ +---------------------------------+
| struct s { | | struct s; |
| int internal; | | |
| int other_stuff; | | extern void |
| }; | | api_func(struct s *foo, int x); |
| | +---------------------------------+
| extern void | +---------------------------------+
| api_func(struct s *foo, int x); | | #include "api.h" |
+---------------------------------+ | |
+---------------------------------+ | struct s { |
| #include "api.h" | | int internal; |
| | | int other_stuff; |
| void | | }; |
| api_func(struct s *foo, int x) | | |
| { | | void |
| foo->internal = x; | | api_func(struct s *foo, int x) |
| } | | { |
+---------------------------------+ | foo->internal = x; |
| } |
+---------------------------------+
Este cliente de la API funciona con cualquiera de las versiones:
#include "api.h"
void good(struct s *foo)
{
api_func(foo, 123);
}
Este se da vueltas en los detalles de implementación:
#include "api.h"
void bad(struct s *foo)
{
foo->internal = 123;
}
que funcionará con la versión "definición en encabezado", pero no con la versión "definición en implementación", ya que en este último caso el compilador no tiene visibilidad del diseño de la estructura:
$ gcc -Wall -c bad.c
bad.c: In function ''bad'':
bad.c:5: error: dereferencing pointer to incomplete type
$
Por lo tanto, la versión de "definición en implementación" protege contra el uso indebido accidental o deliberado de los detalles de la implementación privada.
El punto es que colocarlo en un archivo de encabezado le permite usar la estructura (o cualquier otra definición) desde múltiples archivos fuente, simplemente incluyendo ese archivo de encabezado.
Pero si está seguro de que solo se utilizará a partir de un archivo fuente, entonces realmente no hace ninguna diferencia.
En general, no creo que haya una gran diferencia si los pones en el encabezado o en los archivos fuente. Sin embargo, si necesita acceder a los miembros de una estructura desde múltiples archivos fuente, es más fácil poner la estructura en un archivo de encabezado e incluirlo desde cualquier otro archivo donde se necesite la estructura.
Las estructuras privadas para ese archivo deben ir en el archivo .c, con una declaración en el archivo .h si son utilizadas por cualquier función en .h.
Las estructuras públicas deberían ir en el archivo .h.
Los puse en el archivo C para hacerlo más orientado a objetos, mira este artículo .
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), la coloca en ese archivo .c.