Historique de la question :
En langage C, il arrive parfois qu'une structure doive "connaître" une autre, mais en même temps, la définition des deux structures dépend l'une de l'autre (imbriquement mutuel). Il est alors impossible de définir complètement une structure avant de déclarer la seconde. Pour cela, C prévoit la déclaration anticipée des structures.
Problème :
Sans déclaration anticipée, le compilateur ne sait pas quel type il rencontre à l'intérieur de la structure et renverra une erreur de type inconnu. Une erreur survient souvent lorsque nous essayons de créer une structure qui contient une autre par valeur, et non par pointeur, ou lorsque nous écrivons incorrectement la syntaxe.
Solution :
La déclaration anticipée est utilisée lorsque vous devez créer un pointeur vers une structure sans révéler sa définition complète. La syntaxe est struct A;. La définition complète (struct A { ... };) peut être donnée plus tard.
Exemple de code :
struct B; // déclaration anticipée struct A { int val; struct B *link; }; struct B { int id; struct A *parent; };
Caractéristiques clés :
Peut-on faire un champ de type "autre structure par valeur" via déclaration anticipée ?
Non, la déclaration anticipée permet d'utiliser le type uniquement sous forme de pointeur, sinon il y aura une erreur : la taille du type est inconnue.
struct B; // ok struct A { struct B b; // erreur : taille de B inconnue };
Où placer correctement la déclaration anticipée lors de l'utilisation de différents fichiers ?
On place la déclaration anticipée dans l'en-tête, si la structure n'est utilisée que comme pointeur. La définition complète doit être soit dans un autre en-tête, soit dans le fichier d'implémentation.
La déclaration anticipée affecte-t-elle la taille des structures et la bonne allocation de mémoire ?
Non, car C ne connaît pas la taille de la structure "non définie", et un pointeur a toujours la même taille pour ce compilateur, indépendamment du type déclaré.
Dans le fichier d'en-tête, les deux modules contenaient des structures avec des champs de l'autre par valeur. La compilation échouait avec une erreur de type indéterminé.
Avantages :
Inconvénients :
L'un des programmeurs a utilisé une déclaration anticipée et des pointeurs, minimisant les dépendances redondantes dans les en-têtes. La compilation et la maintenance du code sont devenues plus simples.
Avantages :
Inconvénients :