web-dev-qa-db-fra.com

C Nom de type inconnu 'ma_structure'

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?

11
alexandernst

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:

  1. UTILSH est défini
  2. MAINH est défini
  3. Parce que UTILSH est déjà défini, nous ne traitons pas my_struct.h À nouveau, donc le typedef n'est pas traité
  4. void some_func(my_structure *x); est traitée.
  5. Maintenant le typedef est traité.

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.

19
John Bode

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.

6
AnT

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.

3
yan