Verhindern von rekursivem C # include

7

Ich verstehe grob die Regeln mit dem, was # include mit dem C Präprozessor macht, aber ich verstehe es nicht vollständig. Im Moment habe ich zwei Header-Dateien, Move.h und Board.h, die beide ihren jeweiligen Typ eingeben (Move und Board). In beiden Header-Dateien muss ich auf den Typ verweisen, der in der anderen Header-Datei definiert ist.

Im Moment habe ich # Move.h in Board.h enthalten und # Board.h in Move.h. Wenn ich jedoch kompiliere, kippt gcc aus und gibt mir eine lange (was wie unendlich rekursiv aussieht) Fehlermeldung zwischen Move.h und Board.h.

Wie schließe ich diese Dateien so ein, dass ich sie nicht rekursiv einschließe?

    
twolfe18 11.01.2010, 21:43
quelle

7 Antworten

14

Sie müssen in Vorwärtsdeklarationen suchen , Sie haben endlose Schleifen von Includes erstellt, Vorwärtsdeklarationen sind die richtige Lösung.

Hier ist ein Beispiel:

Verschieben.h

%Vor%

Board.h

%Vor%

main.c

%Vor%

Hinweis: Wenn Sie ein "Board" erstellen, müssen Sie so etwas tun (es gibt ein paar Möglichkeiten, hier ein Beispiel):

%Vor%     
Evan Teran 11.01.2010, 21:45
quelle
3

Wächter sollten Teil der Lösung für dieses Problem sein.

Beispiel aus Wikipedia:

%Vor%

Ссылка

Der andere Teil, wie er von einigen anderen erwähnt wird, ist die Vorwärtsreferenzierung. ( Ссылка )

Sie können eine der Strukturen über der anderen wie folgt deklarieren:

%Vor%     
Steve Strickland 11.01.2010 21:50
quelle
2

Wie so:

%Vor%

Auf diese Weise kann Board.h ohne Abhängigkeit von move.h kompiliert werden, und Sie können board.h von move.h einfügen, um den Inhalt dort verfügbar zu machen.

    
Igor Zevaka 11.01.2010 21:50
quelle
2

Zunächst scheint es, dass Wächter in Ihren .h -Dateien nicht enthalten sind, sodass Sie sie rekursiv einschließen. Das ist schlecht.

Zweitens können Sie eine Vorwärtsdeklaration durchführen. In Move.h :

%Vor%

In Board.h :

%Vor%

Beachten Sie, dass diese Methode nicht funktioniert, wenn Sie in beiden Dateien struct Move und struct Board -Objekte deklarieren müssen (anstatt Zeiger auf einen von ihnen). Dies liegt daran, dass einer der Typen zum Zeitpunkt des Parsens einer der Dateien ein unvollständiger Typ ist ( struct Move im obigen Beispiel).

Wenn Sie also die Typen in beiden Dateien verwenden müssen, müssen Sie die Typdefinitionen trennen: haben Header-Dateien, die struct Move und struct Board definieren, und nichts anderes (etwas wie mein Beispiel oben) und dann eine andere Headerdatei verwenden, die sowohl auf struct Move als auch auf struct Board verweist.

Natürlich können Sie nicht struct Move contain eine struct Board und struct Board gleichzeitig struct Move enthalten - das wird eine unendliche Rekursion sein, und die Strukturgrößen sind auch unendlich!

    
Alok Singhal 11.01.2010 21:57
quelle
0

Sie müssen zuerst einen von ihnen haben. Machen Sie eine Vorwärtsdecl in einer von ihnen und haben Sie diese für zum Beispiel

%Vor%

könnte Teil der board.h-Datei sein.

und

%Vor%

könnte Teil der Datei move.h sein

Dann könnten Sie sie in beliebiger Reihenfolge hinzufügen.

Bearbeiten Wie in den Kommentaren darauf hingewiesen wurde ... nahm ich die Verwendung des typedef-Konstrukts für die Board-Struktur wie folgt an:

%Vor%

Da ich noch nie jemanden gesehen habe, der Strukturen in C ohne Typdef verwendet, habe ich diese Annahme gemacht ... vielleicht haben sich die Dinge seit der letzten Kodierung in C geändert (yikies .... es war vor 15 Jahren)

    
Hogan 11.01.2010 21:46
quelle
0

Circular Abhängigkeiten sind ein Schmerz in den Arsch und sollte beseitigt werden, wo immer möglich. Zusätzlich zu den bisher gegebenen Vorwärtsdeklarationsvorschlägen (Aloks ist das beste Beispiel) möchte ich einen weiteren Vorschlag in die Arbeit werfen: die gegenseitige Abhängigkeit zwischen Board und Move durch Einführung eines dritten Typs (nennen wir es BoardMoveAssoc zur Veranschaulichung; Ich bin mir sicher, dass du einen weniger bescheuerten Namen finden kannst):

%Vor%

Nach diesem Schema müssen Board und Move nichts voneinander wissen; Alle Verknüpfungen zwischen den beiden werden vom Typ BoardMoveAssoc verwaltet. Die genaue Struktur hängt davon ab, wie Move und Board zusammenhängen sollen. Wenn z. B. mehrere Züge einer einzelnen Karte zugeordnet sind, sieht die Struktur möglicherweise eher wie

aus %Vor%

Auf diese Weise müssen Sie sich nicht um Vorwärtsdeklarationen oder unvollständige Typen kümmern. Sie führen einen dritten Typ in den Mix ein, aber ich glaube, dass dies leichter zu verstehen und zu pflegen ist.

    
John Bode 11.01.2010 22:39
quelle
0

Von K & amp; R Die C-Programmiersprache (S. 91 "Bedingte Aufnahme" in meiner Kopie), mit einigen Verbesserungen für Sie:

%Vor%

und dasselbe für Move.h

Auf diese Weise wird, sobald ein Header einmal eingeschlossen wurde, dieser nicht erneut eingefügt, da der Name 'BOARD_H' bereits für den Präprozessor definiert wurde.

    
Nij 11.01.2010 21:55
quelle

Tags und Links