Forum: Compiler & IDEs ? zu typedef struct in .h-Dateien


von Thomas P. (topla)


Lesenswert?

Hallo,

ich habe ein Problem mit "typedef struct" in Header-Dateien im 
Zusammenhang mit einer (Array)Definitionen. Im Prinzip sieht das so aus:

datei1.h
1
#include datei2.h
2
typedef struct
3
{
4
...
5
} daten1_t;                 //<<
6
extern daten1_t daten[32];  //<<

datei1.c
1
#include datei1.h
2
...
3
daten1_t daten1[32];
4
...

datei2.h
1
#include datei2.h
2
#include datei1.h
3
...

datei2.c
1
#include datei2.h
2
...

In dieser Konstellation braucht der Compiler ewig und wirft tonnenweise 
Fehler, die auf Rekursion "error: #include nested too deeply" hinweisen. 
Schiebt man die Zeile "#include datei2.h" aus der "datei1.h" in die 
"datei1.c" ergibt sich der gleiche Fehler "...error: conflicting types 
for 'daten1' nur noch zweimal in den markierten Zeilen (//<<).

Problem ist offensichtlich die Deklaration (es gibt keine Definitionen 
in den .h-Dateien) "über Kreuz" und ich weiß hier nicht weiter. Bei der 
Suche bin ich auch auf Hinweise auf Rekursion gestoßen, aber wie hebt 
man das auf?
Und wieso kann man .h-Dateien nicht mehrfach einbinden, wenn keine 
Definitionen darin enthalten sind?

Ich bitte die Kundigen um Aufklärung des Unwissenden...

Thomas

von Peter II (Gast)


Lesenswert?

teste mal mit einen include guard

https://de.wikipedia.org/wiki/Include-Guard

von g457 (Gast)


Lesenswert?

> Problem ist offensichtlich die Deklaration (es gibt keine Definitionen
>in den .h-Dateien) "über Kreuz" und ich weiß hier nicht weiter.

Nein. Das Problem ist das
1
#include datei2.h
 in datei1.h. Das brauchts hier nicht. Wenn es doch nötig ist (weil dort 
Typen vereinbart werden, die in daten1_t benötigt werden), dann lautet 
das Stichwort include guard.

HTH

von Thomas P. (topla)


Lesenswert?

Danke für die Hinweise, aber das Problem bleibt leider trotzdem 
bestehen. Irgendwie hängt das wohl doch mit der typedef struct zusammen.

Thomas

edit: Das #include datei2.h benötige ich wegen der dort vorhandenen 
Funktionsdeklarationen.

: Bearbeitet durch User
von Berecke (Gast)


Lesenswert?

Ähm,
datei2.h ruft sich rekursiv auf?
1
#include datei2.h
2
#include datei1.h
3
...

von Thomas P. (topla)


Lesenswert?

Ja, das habe ich nach den Hinweise von oben mit "include guard" behoben 
und eine Fehlergruppe "error: #include nested too deeply" ist weg.
Bleiben trotzdem die Fragen:
1. Warum kann ich .h-Dateien mit "typedef struct"-Inhalt (die aber keine 
Definitionen enthalten) nicht beliebig inkludieren? Laut meinem 
zusammengekratztem Anfängerwissen sind das doch "nur" harmlose 
Vorwärtsdeklarationen.
2. Warum erscheint der Fehler "...error: conflicting types for daten1"? 
Welcher Konflikt soll das denn sein?
3. Habe ich es vielleicht falsch verstanden, dass die "typedef struct" 
und die extern-Deklaration in die .h-Datei gehören und nur die 
Definition im .c-File steht?

Thomas

von Rolf M. (rmagnus)


Lesenswert?

Thomas P. schrieb:
> 1. Warum kann ich .h-Dateien mit "typedef struct"-Inhalt (die aber keine
> Definitionen enthalten) nicht beliebig inkludieren? Laut meinem
> zusammengekratztem Anfängerwissen sind das doch "nur" harmlose
> Vorwärtsdeklarationen.

Häng bitte mal ein paar Dateien an, die deiner Meinung nach so durch den 
Compiler gehen müßten, aber den Fehler zeigen, so daß man das 
nachstellen kann.

> 2. Warum erscheint der Fehler "...error: conflicting types for daten1"?
> Welcher Konflikt soll das denn sein?

Den Codefragmenten, die du oben gepostet hast nach, keiner.

> 3. Habe ich es vielleicht falsch verstanden, dass die "typedef struct"
> und die extern-Deklaration in die .h-Datei gehören und nur die
> Definition im .c-File steht?

Nein, das passt so.


Am Rande noch: Du sprichst hier immer vom "typedef struct". Tatsächlich 
sind typedef und struct zwei komplett getrennte Sachen, die erstmal 
nichts mit einander zu tun haben. Du hast dich da lediglich entschieden, 
eine Struktur-Definition und die Definition eines Typedefs 
zusammenzuführen.

: Bearbeitet durch User
von Planlos (Gast)


Lesenswert?

Zeig deine include guards, für beide .h

von Thomas P. (topla)


Lesenswert?

Meine Erkenntnisse als Anfänger:

Die beiden include guards:
#ifndef w_up_h
#define w_up_h
#include <w_up.h>
#endif

#ifndef x_h
#define x_h
#include <x.h>
#endif

müssen nicht nur in den h.-Dateien (so hatte ich den verlinkten Artikel 
verstanden) sondern auch in den .c-Dateien für die jeweils eigene 
.h-Datei vorhanden sein, dann funktioniert die ganze Sache.
Alternativ lässt sich das auch durch die Präprozessordirektive #pragma 
once lösen, damit spart man sich die include guards. Funktioniert in 
meinem Fall auch.
Mal schauen, ob ich ein Beispiel zusammenbringe. das ganze Projekt ist 
nix für eine Veröffentlichung.

Thomas

von Planlos (Gast)


Lesenswert?

Die guards gehören in die .h -Dateien selbst, nicht um deren #include

von Thomas P. (topla)


Lesenswert?

Ja, war mir gerade beim nochmaligen Lesen des Wikis auch aufgefallen. 
Ich hatte das erst nur auf die kreuzweisen includes in den .h-Dateien 
bezogen und der zweite include guard im .c-File hat es dann gerichtet.
Gut, Lösung also vorhanden und funktioniert, wieder was gelernt. Mal 
sehen, wo und wie ich mir das nächste Problem einbaue.

Thomas

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.