Gegenseitige Includes, zyklische Abhängigkeiten
-
Hallo zusammen,
Wenn ich probiere folgende Files zu compilieren kommt immer der Fehler
syntax error before "QATuple" in manager.h.Was zum Henker mache ich falsch. Sitze schon mehrere Stunden an dem Problem
und komme nich weiter.Benutze MinGw mit Eclipse, hab es aber auch in Visual Studio versucht mit gleichem Resultat.
Eine Sache konnte ich rausfinden, wenn ich die Source Datei uestion.c aus
dem Projekt rausschmeiße und nicht mitcompiliere kommt kein Fehler.ich habe folgende Source und Header Files
manager.h
#ifndef MANAGER_H_ #define MANAGER_H_ #include "uestion.h" int getNewQATupel(int p1, QATuple *qa); #endifmanager.c
#include "manager.h" #define MAX 25 int getNewQATupel(int p1, QATuple *outAnswer){ return 0; }uestion.h
#ifndef UESTION_H_ #define UESTION_H_ #include "manager.h" typedef struct questionAnswersTuple{ const char* question; const char* answer; const char* wrongAnswers[3]; }QATuple; typedef enum success { FAIL, PASS, EXIT }SUCCESS; SUCCESS ask(QATuple* question, int* Punkte, int* fiftyJoker, int* changeJoker); #endifuestion.c
#include "uestion.h" SUCCESS ask2(QATuple* question, int anzahl, int* punkte, int* fiftyJoker, int* changeJoker); SUCCESS ask(QATuple* question, int* punkte, int* fiftyJoker, int* changeJoker) { return ask2(question, 4, punkte, fiftyJoker, changeJoker); } SUCCESS ask2(QATuple* question, int anzahl, int* punkte, int* fiftyJoker, int* changeJoker) { return FAIL; }Bitte helft mir
Mfg
roskas
-
manager.h und uestion.h inkludieren sich gegenseitig. In uestion.c führt das dazu, daß QAtuple unbekannt ist, weil dort zuerst uestion.h inkludiert wird, dort wird zuerst UESTION_H definiert, jetzt wird manager.h inkludiert. Hier wiederum wird wieder uestion.h inkludiert, allerdings ist jetzt wegen der bereits erfolgten Definition von UESTION_H dieser Include wirkungslos und deshalb QATuple in manager.h unbekannt.
-
mal alles in der c-datei auskommentieren und schrittweise hinzufügen, bis fehler identifiziert.
-
Ja es liegt tatsächlich am gegenseitigen includen.
1. Lösungsmöglichkeit (leicht verändertes Beispiel):
Dazu muss man in den Headerdateien erst die sachen definieren, die in den anderen Headerdateien benötigt werden und danach erst diese Headerdateien includen.manager.h
#ifndef MANAGER_H_ #define MANAGER_H_ typedef enum _level { HAUS, AUTO, STUHL } Level; #include "uestion.h" void machwas(Haus haus); #endifmanager.c
#include "manager.h" void machwas(Haus haus){}uestion.h
#ifndef UESTION_H_ #define UESTION_H_ typedef struct ha{ int nutzer; }Haus; #include "manager.h" void setLevel(Level l); void test(); #endifuestion.c
#include "uestion.h" void test(){} void setLevel(Level l){}2. Lösungsmöglichkeit
Zitat Prof:
"In der Regel werden bei solch enger Verzahnung von zwei
Modulen die grundlegenden Datenstrukturen (hier die Typdefinitionen) in
eine separate Header-datei ausgelagert, zu der es dann keine .c-Datei gibt."Oder hat jemand noch andere Möglichkeiten die funktionieren?
Mfg
roskas
-
Wenn ich mir Dein erstes Posting ansehe, glaube ich, daß Du dort in uestion.h die Funktionsdeklaration aus manager.h nicht benötigst.
Also wirf das Include aus uestion.h hinaus.
-
In der Regel werden bei solch zyklischen Abhängigkeiten Deklarationen verwendet, um dem Compiler mitzuteilen, dass es einen bestimmten Typ gibt, aber nicht, was dieser enthält. Deklarationen (in diesem Zusammenhang auch Vorausdeklarationen genannt) sind überall dort ausreichend, wo der Compiler den Inhalt eines Typs nicht kennen muss.
Beispiel:
#ifndef MANAGER_H_ #define MANAGER_H_ // hier stehen die Innereien von QATuple drin. Die brauchen wir hier aber noch nicht. // #include "uestion.h" // getNewQATupel wird ein Zeiger übergeben. Dem Compiler reicht es, zu wissen, dass QATuple ein Typedef einer Struktur ist. typedef struct questionAnswersTuple QATuple; int getNewQATupel(int p1, QATuple *qa); #endifErst in der Implementierung von getNewQATupel muss die Struktur (vermutlich) bekannt sein. Deshalb musst Du in manager.c sowohl manager.h als auch uestion.h einbinden.
BTW: Meiner Meinung nach ist das include manager.h in uestion.h völlig unnötig.