C Unbekannter Typname „my_structure“

Lesezeit: 3 Minuten

Alexandernsts Benutzeravatar
Alexandernst

Ich habe diesen Code:

main.h

#ifndef MAINH
#define MAINH
...
#include "my_struct.h"
void some_func(my_structure *x);
...
#endif

Und

my_struct.h

#ifndef UTILSH
#define UTILSH
...
#include "main.h"
...
typedef struct abcd {
    int a;
} my_structure;
...
#endif

Aber ich bekomme Folgendes, wenn ich versuche zu kompilieren: error: unknown type name ‘my_structure’

Irgendeine Idee warum?

John Bodes Benutzeravatar
John Bode

Aufgrund der Art und Weise, wie Sie Ihre Includes bestellt haben, sieht der Compiler dies void some_func(my_structure *x); bevor es sieht typedef struct abcd { int a; } my_structure;.

Lassen Sie uns das durchgehen.

Vorausgesetzt my_struct.h Wird zuerst verarbeitet, erhalten wir die folgende Abfolge von Ereignissen:

  1. UTILSH ist definiert
  2. MAINH ist definiert
  3. Weil UTILSH ist bereits definiert, wir verarbeiten es nicht my_struct.h Auch hier wird die Typdefinition nicht verarbeitet
  4. void some_func(my_structure *x); verarbeitet wird.
  5. Jetzt Die typedef verarbeitet wird.

Nach der Vorverarbeitung sieht Ihr Compiler also die folgende Folge von Deklarationen:

...
void some_func(my_structure *x);
...
typedef struct abcd {...} my_structure;

Schlechtes Juju. Sie benötigen entweder eine Vorwärtsdeklaration von my_structure In main.h, oder Sie müssen diese zirkuläre Abhängigkeit durchbrechen (was die am meisten bevorzugte Option ist). Ist da irgendetwas drin? main.h Das my_structure.h tatsächlich verwendet? Wenn ja, sollten Sie es in eine separate Datei ausgliedern, die beides enthält main.h Und my_structure.h enthalten.

  • Ja, main.h enthält alles, was meine App benötigt. Ich schätze, ich könnte meinen Code umgestalten/bereinigen. Ich war mir einfach nicht sicher, ob es daran lag

    – Alexandernst

    19. September 2013 um 19:35 Uhr

AnT steht auf der Seite des russischen Benutzer-Avatars
AnT steht an der Seite Russlands

Sie haben eine kreisförmige Header-Inklusion erstellt. Zirkuläre Inklusion bringt nie etwas. Es ist unendlich. Der #ifndef include Guard unterbricht den unendlichen Einschlusskreis an einem unvorhersehbaren Punkt (abhängig davon, in welchen Header eingebunden wird). .c Datei zuerst). Das ist in Ihrem Fall passiert. Im Grunde genommen wurde Ihre kreisförmige Einbeziehung in Einbeziehung „aufgelöst“. main.h zuerst und my_struct.h zweite. Deshalb main.h weiß nichts darüber my_struct Typ.

Auch hier wird durch zirkuläre Inklusion nie etwas erreicht. Befreien Sie sich von der zirkulären Inklusion. Gestalten Sie Ihre Header-Struktur hierarchisch: Header niedrigerer Ebene werden in Header höherer Ebene eingefügt, aber niemals umgekehrt. In Ihrem Fall my_struct.h handelt es sich wahrscheinlich um einen Header auf niedrigerer Ebene, was bedeutet, dass Sie mit dem Einbinden aufhören müssen main.h hinein my_struct.h. Gestalten Sie Ihre Header so neu my_struct.h nicht mehr benötigt main.h.

  • “brechen […] Inklusionskreis bei manchen unvorhersehbarer Punkt“: Danke für dieses Detail. Genau der Teil, der mir fehlte, um ihn zu verstehen.

    – BaldDude

    12. Januar 2021 um 12:55 Uhr


Die Fehlermeldung kommt von main.h solange es darin enthalten ist my_struct.hVor my_structure ist definiert. Sie sollten Ihre Include-Pfade seitdem überdenken main.h Und my_struct.h einander einbeziehen.

Sie wollen wahrscheinlich Ihre main.h Datei, die einfach eingebunden werden soll my_struct.hund nicht haben my_struct.h irgendetwas einschließen. Sie weisen Ihren C-Compiler im Wesentlichen an, eine unendliche Co-Include-Schleife zu haben.

  • Ist aber nicht vorgesehen MAINH um mich davor zu schützen?

    – Alexandernst

    19. September 2013 um 19:32 Uhr

  • Es schützt Sie davor, es zweimal einzuschließen, aber Sie fügen es trotzdem ein main.h aus my_struct.h wenn ich glaube, dass Sie das Gegenteil beabsichtigen.

    – Yan

    19. September 2013 um 19:36 Uhr

  • @alexandernst Sie sollten die Includes außerhalb der ifndef-Direktive platzieren, damit sie wie erwartet funktionieren

    – SwiftMango

    19. September 2013 um 19:37 Uhr

  • @alexandernst: Es tut schütze dich vor unendlicher Inklusion. Der Fehler, den Sie erhalten, ist jedoch eine direkte Folge dieses „Schutzes“.

    – AnT steht an der Seite Russlands

    19. September 2013 um 19:39 Uhr


1452740cookie-checkC Unbekannter Typname „my_structure“

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy