Historia de la cuestión:
En el lenguaje C, a veces es necesario que una estructura "conozca" a otra, pero la definición de ambas estructuras depende una de la otra (anidación mutua). Por lo tanto, no es posible definir completamente una estructura antes de la declaración de la segunda. Para esto, C proporciona la declaración anticipada (forward declaration) de estructuras.
Problema:
Sin declaración anticipada, el compilador no sabe qué tipo se encuentra dentro de la estructura y mostrará un error de tipo desconocido. A menudo se produce un error cuando intentamos crear una estructura que contenga otra por valor, y no por puntero, o cuando escribimos incorrectamente la sintaxis.
Solución:
La declaración anticipada se utiliza si se necesita crear un puntero a una estructura sin revelar su definición completa. La sintaxis es struct A;. La definición completa (struct A { ... };) se puede proporcionar más tarde.
Ejemplo de código:
struct B; // declaración anticipada struct A { int val; struct B *link; }; struct B { int id; struct A *parent; };
Características clave:
¿Se puede hacer un campo de tipo "otra estructura por valor" a través de la declaración anticipada?
No, la declaración anticipada permite usar el tipo solo en forma de puntero, de lo contrario, habrá un error: el tamaño del tipo es desconocido.
struct B; // ok struct A { struct B b; // error: el tamaño de B es desconocido };
¿Dónde se debe colocar correctamente la declaración anticipada al trabajar con diferentes archivos?
La declaración anticipada se coloca en el encabezado si la estructura se usa solo como puntero. La definición completa se puede encontrar en otro encabezado o en el archivo de implementación.
¿Afecta la declaración anticipada el tamaño de las estructuras y la correcta asignación de memoria?
No, porque C no conoce el tamaño de la estructura "no definida", y un puntero siempre tiene el mismo tamaño para un compilador dado, independientemente del tipo declarado.
En el archivo de encabezado, ambos módulos contenían estructuras con campos entre sí por valor. La compilación fallaba con un error de tipo indefinido.
Ventajas:
Desventajas:
Uno de los programadores utilizó declaración anticipada y punteros, minimizando las dependencias excesivas en los encabezados. La compilación y el mantenimiento del código se volvieron más simples.
Ventajas:
Desventajas: