375 Stimmen

Reihenfolge der C/C++-Include-Header-Dateien

In welcher Reihenfolge sollten Include-Dateien angegeben werden, d.h. was sind die Gründe für die Aufnahme eines Headers vor einem anderen?

Werden zum Beispiel die Systemdateien, STL und Boost vor oder nach den lokalen Include-Dateien eingefügt?

17voto

clstrfsck Punkte 14455

Ich bin mir ziemlich sicher, dass dies nirgendwo auf der Welt empfohlen wird, aber ich reihe System-Includes gerne nach der Länge des Dateinamens auf, lexikalisch sortiert innerhalb der gleichen Länge. Zum Beispiel so:

#include <set>
#include <vector>
#include <algorithm>
#include <functional>

Ich denke, es ist eine gute Idee, die eigenen Header vor den anderen einzubinden, um die Schande der Include-Reihenfolge-Abhängigkeit zu vermeiden.

7voto

wilhelmtell Punkte 55189

Dies ist nicht subjektiv. Vergewissern Sie sich, dass Ihre Überschriften nicht davon abhängen, dass sie #include d in einer bestimmten Reihenfolge. Sie können sicher sein, dass es keine Rolle spielt, in welcher Reihenfolge Sie STL- oder Boost-Header einfügen.

5voto

Agnel Kurian Punkte 55747

Fügen Sie zunächst den Header ein, der der .cpp entspricht... mit anderen Worten, source1.cpp sollte umfassen source1.h bevor Sie etwas anderes hinzufügen. Die einzige Ausnahme, die mir einfällt, ist die Verwendung von MSVC mit vorkompilierten Headern, in diesem Fall sind Sie gezwungen, die stdafx.h vor allem anderen.

Begründungen: Einschließlich der source1.h vor allen anderen Dateien stellt sicher, dass es ohne seine Abhängigkeiten allein stehen kann. Wenn source1.h eine Abhängigkeit zu einem späteren Zeitpunkt aufnimmt, wird der Compiler Sie sofort darauf hinweisen, die erforderlichen Forward-Deklarationen zu source1.h . Dies wiederum stellt sicher, dass Kopfzeilen in beliebiger Reihenfolge von ihren Untergebenen eingefügt werden können.

Beispiel:

source1.h

class Class1 {
    Class2 c2;    // a dependency which has not been forward declared
};

source1.cpp

#include "source1.h"    // now compiler will alert you saying that Class2 is undefined
                    // so you can forward declare Class2 within source1.h
...

MSVC-Benutzer: Ich empfehle dringend, vorkompilierte Header zu verwenden. Verschieben Sie also alle #include Richtlinien für Standardkopfzeilen (und andere Kopfzeilen, die sich nie ändern werden) zu stdafx.h .

4voto

shuhalo Punkte 5262

Bei der Entscheidung für eine bestimmte Einschlussreihenfolge werden mehrere Überlegungen miteinander verknüpft. Lassen Sie mich versuchen, das zu entwirren.

1. Prüfung auf Geschlossenheit

Viele Antworten deuten darauf hin, dass die Include-Reihenfolge als Kontrolle dafür dienen sollte, dass Ihre Kopfzeilen in sich geschlossen sind. Das verwechselt die Berücksichtigung von Testen y Zusammenstellung

Sie können separat prüfen, ob Ihre Kopfzeilen selbst eingeschlossen sind. Diese "statische Analyse" ist unabhängig von jedem Kompilierungsprozess. Führen Sie zum Beispiel

gcc headerfile.h -fsyntax-only

Die Prüfung, ob Ihre Header-Dateien in sich geschlossen sind, lässt sich leicht durch Skripte automatisieren. Sogar Ihr Makefile kann das tun.

Nichts für ungut, aber das Buch von Lakos stammt aus dem Jahr 1996, und die Kombination dieser verschiedenen Anliegen klingt für mich wie eine Programmierung im Stil der 90er Jahre. Davon abgesehen gibt es Ökosysteme (Windows heute oder in den 90ern?), denen die Werkzeuge für geskriptete/automatisierte Tests fehlen.

2. Lesbarkeit

Eine weitere Überlegung ist Lesbarkeit . Wenn Sie in Ihrer Quelldatei nachsehen, wollen Sie einfach sehen, welche Dinge enthalten sind. Dabei kommt es vor allem auf Ihren persönlichen Geschmack und Ihre Vorlieben an. Üblicherweise ordnen Sie sie entweder vom spezifischsten zum unspezifischsten oder umgekehrt (ich bevorzuge Letzteres).

Innerhalb der einzelnen Gruppen ordne ich sie in der Regel nur alphabetisch ein.

3. Spielt die Reihenfolge der Aufnahme eine Rolle?

Wenn Ihre Header-Dateien in sich geschlossen sind, dann ist die Reihenfolge der Includes technisch gesehen sollte überhaupt keine Rolle spielen für das Kompilierungsergebnis.

Das heißt, es sei denn, Sie haben (fragwürdige?) spezifische Design-Entscheidungen für Ihren Code, wie z.B. notwendige Makro-Definitionen, die nicht automatisch einbezogen werden. In diesem Fall sollten Sie Ihr Programmdesign überdenken, auch wenn es für Sie natürlich perfekt funktionieren könnte.

3voto

dcw Punkte 3411

Binden Sie von der spezifischsten zur am wenigsten spezifischen ein, beginnend mit der entsprechenden .hpp für die .cpp, falls eine solche existiert. Auf diese Weise werden alle versteckten Abhängigkeiten in Header-Dateien, die nicht autark sind, aufgedeckt.

Dies wird durch die Verwendung von vorkompilierten Headern erschwert. Eine Möglichkeit, dies zu umgehen, ohne das Projekt compilerspezifisch zu machen, besteht darin, einen der Projektheader als vorkompilierte Header-Include-Datei zu verwenden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X