alejandro
tengo este codigo:
main.h
#ifndef MAINH
#define MAINH
...
#include "my_struct.h"
void some_func(my_structure *x);
...
#endif
y
my_struct.h
#ifndef UTILSH
#define UTILSH
...
#include "main.h"
...
typedef struct abcd {
int a;
} my_structure;
...
#endif
pero obtengo esto cuando intento compilar: error: unknown type name ‘my_structure’
¿Alguna idea de por qué?
Juan Bode
Debido a cómo ordenó sus inclusiones, el compilador ve void some_func(my_structure *x);
antes de que vea typedef struct abcd { int a; } my_structure;
.
Repasemos esto.
Asumiendo my_struct.h
se procesa primero, obtenemos la siguiente secuencia de eventos:
UTILSH
se defineMAINH
se define- Porque
UTILSH
ya está definido, no procesamosmy_struct.h
de nuevo, por lo que el typedef no se procesa void some_func(my_structure *x);
es procesado.- Ahora el
typedef
es procesado.
Entonces, después del preprocesamiento, su compilador ve la siguiente secuencia de declaraciones:
...
void some_func(my_structure *x);
...
typedef struct abcd {...} my_structure;
Juju malo. O bien necesita una declaración anticipada de my_structure
en main.h
, o necesita romper esa dependencia circular (que es la opción preferida). ¿Hay algo en main.h
eso my_structure.h
realmente usa? Si es así, querrá factorizarlo en un archivo separado que main.h
y my_structure.h
incluir.
-
Sí, main.h incluye todo lo que necesita mi aplicación. Supongo que podría refactorizar/limpiar mi código. No estaba seguro de que fuera por eso.
– alexandernst
19/09/2013 a las 19:35
AnT apoya a Rusia
Ha creado una inclusión de encabezado circular. La inclusión circular nunca logra nada. es infinito El #ifndef
include guard romperá el círculo de inclusión infinito en algún punto impredecible (dependiendo de qué encabezado se incluye en .c
archivo primero). Esto es lo que sucedió en tu caso. Básicamente, su inclusión circular se “resolvió” para incluir main.h
primero y my_struct.h
segundo. Esta es la razón por main.h
no sabe nada de my_struct
tipo.
Nuevamente, la inclusión circular nunca logra nada. Deshazte de la inclusión circular. Diseñe su estructura de encabezado jerárquicamente: los encabezados de nivel inferior se incluyen en los encabezados de nivel superior, pero nunca al revés. En tu caso my_struct.h
es probablemente un encabezado de nivel inferior, lo que significa que debe dejar de incluir main.h
en my_struct.h
. Rediseñe sus encabezados para que my_struct.h
ya no necesita main.h
.
-
“romper […] círculo de inclusión en algunos punto impredecible” : Gracias por ese detalle. Exactamente la parte que me faltaba por entender.
– Amigo calvo
12 de enero de 2021 a las 12:55
El mensaje de error proviene de main.h
mientras está incluido en my_struct.h
antes my_structure
se define. Debe repensar sus rutas de inclusión ya que main.h
y my_struct.h
incluirse unos a otros.
Probablemente quieras tu main.h
archivo para incluir my_struct.h
y no tener my_struct.h
para incluir cualquier cosa. Básicamente, le está dando instrucciones a su compilador de C para que tenga un ciclo de co-inclusión infinito.
-
pero no se supone
MAINH
para protegerme de esto?– alexandernst
19/09/2013 a las 19:32
-
Te protegerá de incluirlo dos veces, pero aún estás incluyendo
main.h
demy_struct.h
cuando creo que pretendes hacer lo contrario.– yan
19/09/2013 a las 19:36
-
@alexandernst Debería poner los include fuera de la directiva ifndef para que funcionen como esperaba
– SwiftMango
19/09/2013 a las 19:37
-
@alexandernst: Es hace protegerte de la inclusión infinita. Pero el error que está recibiendo es una consecuencia directa de esa “protección”.
– AnT apoya a Rusia
19/09/2013 a las 19:39