J'ai ce code:
main.h
#ifndef MAINH
#define MAINH
...
#include "my_struct.h"
void some_func(my_structure *x);
...
#endif
et
my_struct.h
#ifndef UTILSH
#define UTILSH
...
#include "main.h"
...
typedef struct abcd {
int a;
} my_structure;
...
#endif
mais j'obtiens ceci quand j'essaye de compiler: error: unknown type name ‘my_structure’
Une idée pourquoi?
En raison de la façon dont vous avez ordonné vos inclusions, le compilateur voit void some_func(my_structure *x);
avant de voir typedef struct abcd { int a; } my_structure;
.
Je pense.
Voyons cela.
En supposant que my_struct.h
Est traité en premier, nous obtenons la séquence d'événements suivante:
UTILSH
est définiMAINH
est définiUTILSH
est déjà défini, nous ne traitons pas my_struct.h
À nouveau, donc le typedef n'est pas traitévoid some_func(my_structure *x);
est traitée.Ainsi, après le prétraitement, votre compilateur voit la séquence de déclarations suivante:
...
void some_func(my_structure *x);
...
typedef struct abcd {...} my_structure;
Mauvais juju. Soit vous avez besoin d'une déclaration directe de my_structure
Dans main.h
, Soit vous devez rompre cette dépendance circulaire (qui est l'option préférée). Y a-t-il quelque chose dans main.h
Que my_structure.h
Utilise réellement? Si tel est le cas, vous souhaiterez le factoriser dans un fichier séparé que main.h
Et my_structure.h
Incluent.
Vous avez créé une inclusion d'en-tête circulaire. L'inclusion circulaire n'aboutit à rien. C'est infini. Le #ifndef
include guard rompra le cercle d'inclusion infini à un moment imprévisible (selon l'en-tête inclus dans .c
fichier en premier). C'est ce qui s'est passé dans votre cas. Fondamentalement, votre inclusion circulaire a été "résolue" en incluant main.h
premier et my_struct.h
seconde. C'est pourquoi main.h
ne sait rien de my_struct
type.
Encore une fois, l'inclusion circulaire n'aboutit à rien. Débarrassez-vous de l'inclusion circulaire. Concevez votre structure d'en-tête de manière hiérarchique: des en-têtes de niveau inférieur inclus dans des en-têtes de niveau supérieur, mais jamais l'inverse. Dans ton cas my_struct.h
est probablement un en-tête de niveau inférieur, ce qui signifie que vous devez arrêter d'inclure main.h
en my_struct.h
. Repensez vos en-têtes pour que my_struct.h
n'a plus besoin de main.h
.
Le message d'erreur provient de main.h
alors qu'il est inclus dans my_struct.h
, avant my_structure
est défini. Vous devriez repenser vos chemins d'inclusion depuis main.h
et my_struct.h
s'incluent mutuellement.
Vous voulez probablement votre main.h
fichier à inclure simplement my_struct.h
, et pas my_struct.h
pour inclure quoi que ce soit. Vous demandez essentiellement à votre compilateur C d'avoir une boucle de co-inclusion infinie.