doppelte Includes vermeiden
-
Hallo Leute
Ich habe mittlerweile in meinem Projekt ca. 20 Headerdateien. Tendenz steigend.
Natürlich gibt es zu den Headerdateien auch nochmal fast so viele Sourcedateien die die Headerdateien includen. Ich versuche in die Headerdateien wenig Include anweisungen reinzubringen, und eher per forward deklarations die Klassen bekannt zu machen. In den Sourcdateien gibts dann immer die Liste mit den IncludesDas Problem ist, dass ich zunehmend mit doppelten deklarationen, also mit doppelt eingebundenen Dateien zu kämpfen habe.
Ich habe schon versucht die Includes mittels Präprozessor nur nachzuladen, wenn sie noch nicht geladen sind, aber so richtig klappt das auch nicht, weil hier und da mal wieder ein auf die andere zeigt und dann wieder includes aus includes geladen werden... na ja ich denke ihr kennt das.

Ich dachte mir nun, okay machst du eine globals die du neben dem eigentlichen Header mit in die Sourcedateo includierst. Nur passiert mir da ja eigentlich wieder das gleiche, dass ich wieder doppelt includiere..
Die globals würd ich schon gern einbauen, aber muß ich dann auch für jedes Include nen Präprozessor setzen um sicherzustellen, dass die jeweilige Datei nur einmal includiert wird, oder gibt es da vielleicht noch andere Möglichkeiten?
Kann es vielleicht sein, dass ich einen Designfehler habe und grundlegende Dinge in meinem Projekt falsch mache?Danke schon mal für euere Hile
Grüße
Daimonion
-
Ein Präprozessor ist ein Teil des Compilers, den kann man nicht setzen, du meinst sicher ein Makro
.
Die gängige Lösung sind schon die Include-Guards, also:#ifndef FOO__H #define FOO__H ... #endifEine nicht standardisierte Lösung (funktioniert aber AFAIK unter MSVC und GCC) ist
#pragma onceDann sollte mehrfaches inkludieren eigentlich unmöglich sein...
Falls sich dadurch Probleme mit zirkulären Abhängigkeiten ergeben, musst du ggf.
forward-Deklarationen verwenden.
Ich persönlich handhabe das mit den Include Dateien so:
Alle nicht oder selten veränderten Header Dateien, also die der Standard-Bibliothek oder anderen fremden Bibliotheken, inkludier ich in der stdafx.h (die Include-Datei für vorkompilierte Header), in jeder Source-Datei.
Meine eigenen Header inkludiere ich über eine main.h oder so, die in jeder Source-Datei inkludiert wird.
In Headern inkludier ich wirklich nur die Header, die unbedingt notwendig sind.
Hat bis jetzt immer ganz gut funktioniert, ggf. halt wie gesagt mit forward-Dekalrationen nachhelfen...Grüße,
Martin
-
Hallo
Ah, danke ich dachte bisher das #pragma once MS spezifisch ist. Da das aber doch eher Programmsprachspezifisch ist, werde ich diese Möglichkeit nutzen um doppelte Includes zu vermeiden.
Danke für dne Hinweis.
Grüße
Daimonion
-
'#pragma' als Präprozessor-Direktive ist im Standard verankert - was für Parameter für ein #pragma er versteht, ist jedoch Sache des Compilers. Und die Angabe '#pragma once' versteht auch längst nicht jeder Compiler (auch wenn sich inzwischen einige an MSVC drangehängt haben). Im Gegensatz dazu versteht JEDER standardkonforme Compiler die "klassischen" Include-Guards (#ifndef...).
-
Ja, das wurde mir durchhaus durch den Beitrag von JimmydaMage bewußt, da ich daraufhin mal geschaut habe was im C++ Standard drin ist.. Da die Software und die nötigen Teile zu 99% mit dem GCC und dem MSVC compiliert werden, gehe ich jetzt einfach mal davon aus das mir #pragma once ausreicht um doppelte Includes auszuschließen.
-
beim GCC ist #pragma once deprecated. Kann also sein das neuere Versionen das nicht mehr unterstützen oder unterstützen werden!
Warum nicht einfach include-Guards nehmen? Ist nun mal das sicherste!
-
was genau spricht gegen include guards?
-
Eigentlich spricht nur meine Faulheit gegen die Include Guards.
Ich will deren Akzeptanz keineswegs absprechen.Momentan entwickele ich ausschließlich auf MSVC und mit diesem Compiler werde ich meine Arbeit auch vorerst abschließen. Spätere Arbeiten an der Software (speziell Plugins) können durchaus mit dem GCC entwickelt werden. Daher hab ich die beiden erwähnt und aus diesen Gründen hab ich mich vorerst für die #pragma direktive entschieden. Es ist gut zu wissen das diese Funktion deprecated ist beim gcc. d.h. wenn ich mal was mit dem gcc mache weiß ich das ich das gar nicht probieren brauch

-
Also ich würde IMMER Include-Guards verwenden, eben weil sie auf jedem ISO-C++ Compiler funktionieren. Der einzige Vorteil, den #pragma once bietet, ist, dass es nicht passieren kann, dass zufällig gleiche Guards kollidieren können.
Da ich aber meine Guards immer nach Header und Namespace bennene (NAmespaces sollte man sowieso immer verwenden!), ist die Chance, dass das passiert verschwindend gering...#ifndef BAR_FOO__H #define BAR_FOO__H namespace bar { ... } #endifDie zusätzliche Schreibarbeit ist IMHO nicht wirklich ein Argument...
Gerade wenn du später Plugin-Entwicklung mit dem GCC ermöglichen möchtest, solltest du die portable Variante wählen...Grüße,
Martin