C Nombre de tipo desconocido ‘mi_estructura’

3 minutos de lectura

avatar de usuario de alexandernst
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é?

Avatar de usuario de John Bode
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:

  1. UTILSH se define
  2. MAINH se define
  3. Porque UTILSH ya está definido, no procesamos my_struct.h de nuevo, por lo que el typedef no se procesa
  4. void some_func(my_structure *x); es procesado.
  5. 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 destaca con el avatar de usuario de Rusia
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.hantes 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.hy 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 de my_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


¿Ha sido útil esta solución?