Beste Reihenfolge bei includes?



  • Hallo,

    welche Reihenfolge bei #includes verwendet ihr?

    Zuerst die eigenen Header und dann die Standard Header:

    // Foo.cpp
    #include "Foo.h"
    #include "MyHeader.h"
    
    #include <string>
    

    Oder erst die Standard Header und dann die eigenen:

    // Foo.cpp
    #include <string>
    
    #include "Foo.h"
    #include "MyHeader.h"
    

    Wie macht man das am besten?



  • Ich nehme immer zuerst die des Compiller.

    0x0ERROR



  • Standardlibrary gefolgt von externen Libraries gefolgt von eigenen. Header einer Gruppe alphabetisch.



  • Ich mach das umgekehrt. Zuerst die eigenen, dann die von unseren Libs und am Schluss die von der STL oder 3rd party.
    Die eigenen sind meist die interessanten. Was interessiert es mich, dass ich da <string> inkludieren muss? Das ist nur ein nebensächlicher technischer Aspekt, der kann irgendwo weiter unten kommen.



  • Eigenes Projekt, dann eigene Libs, dann Thirdparty Libs, dann Windows Zeugs, dann STL/... .
    Also grob: von speziell/nicht-standard zu generisch/standard sortiert.

    Reasoning:
    a) Jedes halbwegs klare und einfache System ist besser als gar kein System
    b) Diese Reihenfolge unterstützt das Finden von fehlenden #include Anweisungen in eigenen Headers
    c) Die Begründung von Mechanics ist auch gut



  • System (Posix/WinAPI/etc) -> STL -> 3rd Party -> Projekt



  • Kellerautomat schrieb:

    Standardlibrary gefolgt von externen Libraries gefolgt von eigenen. Header einer Gruppe alphabetisch.

    +1.

    Mechanics schrieb:

    Die eigenen sind meist die interessanten.

    Genau deshalb packt man sie ja nach unten, dann sind sie näher an dem Code an dem man arbeitet. 😉



  • hustbaer schrieb:

    Eigenes Projekt, dann eigene Libs, dann Thirdparty Libs, dann Windows Zeugs, dann STL/... .
    Also grob: von speziell/nicht-standard zu generisch/standard sortiert.

    +1



  • hustbaer schrieb:

    Eigenes Projekt, dann eigene Libs, dann Thirdparty Libs, dann Windows Zeugs, dann STL/... .
    Also grob: von speziell/nicht-standard zu generisch/standard sortiert.

    👍



  • hustbaer und mechanics machen es falsch.

    Denn cooky451 hat hier nicht nur wegen dem Code recht, sondern es gibt ja auch noch die Präprozessordirektiven.
    Die will ich auch nicht zerstückeln und da in manchen Headers auch Präprozessordirektiven drinstehen ist die einzige richtige Vorgehensweise die Folgende:

    Header für das System, POSIX, Windows usw.
    Header für die STL
    Header für externe 3rd Party Libs
    Header für das eigene Zeugs
    Präprozessordirektiven
    Quellcode



  • Unfehlbarkeitscoder schrieb:

    hustbaer und mechanics machen es falsch.

    Denn cooky451 hat hier nicht nur wegen dem Code recht, sondern es gibt ja auch noch die Präprozessordirektiven.
    Die will ich auch nicht zerstückeln und da in manchen Headers auch Präprozessordirektiven drinstehen ist die einzige richtige Vorgehensweise die Folgende:

    Header für das System, POSIX, Windows usw.
    Header für die STL
    Header für externe 3rd Party Libs
    Header für das eigene Zeugs
    Präprozessordirektiven
    Quellcode

    👍 😃



  • hustbaer schrieb:

    Eigenes Projekt, dann eigene Libs, dann Thirdparty Libs, dann Windows Zeugs, dann STL/... .

    Genauso mache ich es auch.

    Ich hab eigentlich gar nie gross darüber nachgedacht, schien mir so am intuitivsten 🙂



  • Unfehlbarkeitscoder schrieb:

    sondern es gibt ja auch noch die Präprozessordirektiven.

    Echt?



  • Zu der Reihenfolge bei den includes hab ich mal eine Frage.
    Ich hatte vor einiger Zeit mal folgendes Problem, meine Lösung hatte mir aber nie so recht gefallen.

    Also:
    In der useful.h wird u.a. eine Funktion

    double rnd_boxMuller(double sigma);
    

    deklariert. Diese wird in der matrix.h verwendet. In der matrix.h wird die Klasse Matrix<T> deklariert. Außerderdem gibt es in der useful.h folgende Funktionsdeklaration:

    Matrix<double> randomDoubleMatrix(int d1 = 5, int d2 = 5, double min = -1, double max = 1);
    

    Wenn in beiden Headern nun die includes jeweils nach ganz oben schreibe, ergibt sich folgendes Problem: useful.h inkludiert matrix.h, der Kompiler trifft (in der matrix.h) auf den rnd_boxMuller-Aufruf und weiß damit nichts anzufangen (da ja der Funktionsname noch nicht deklariert wurde). Meine Lösung war, in der useful.h zunächst die "rnd_boxMuller" zu deklarieren, dann matrix.h zu inkludieren und anschließend die randomDoubleMatrix-Funktion zu deklarieren. Schön finde ich diese Lösung nicht.

    Wie macht man das richtig?



  • Mit einer Vorwärtsdeklaration des Klassentemplates:

    // useful.h
    
    // Deklaration
    template <typename T>
    class Matrix;
    
    double         rnd_boxMuller(double sigma);
    Matrix<double> randomDoubleMatrix(int d1 = 5, int d2 = 5, double min = -1, double max = 1);
    
    // matrix.h
    #include "useful.h"
    
    // Definition
    template <typename T>
    class Matrix
    {
        // ...
    };
    

    Und mach in Zukunft einen neuen Thread auf, dein Thema hat nichts mit dem hier zu tun!



  • Mechanics schrieb:

    Unfehlbarkeitscoder schrieb:

    sondern es gibt ja auch noch die Präprozessordirektiven.

    Echt?

    Guckst du hier:

    http://www.cpp-tutor.de/cpp/le08/include.html



  • Was willst du damit sagen? In Cpp Dateien verwend ich so gut wie nie irgendwelche Präprozessordirektiven, und wenn, dann gehören die eher zum Code als zu den includes. In Header Dateien dann natürlich Headerguards, das wars aber auch schon, und in Header Dateien hab ich nicht so viele Includes.



  • Erst fremde, dann eigene Header. Grund: wenn man in seinem Header einen Fehler hat (zum Beispiel Semikolon am Ende der Klasse vergessen) kann es sonst passieren, dass der Fehler in irgendeinem Standardheader angezeigt wird.
    Gut, so im Nachhinein betrachtet kein sehr guter Grund, aber wenn man es sich einmal so angewöhnt hat…



  • @ipsec
    Wäre für mich eher ein Grund es anders rum zu machen (also so wie ich es mache, zuerst eigene dann fremde).
    Wenn ich nämlich einen Fehler in einem Standard-Headerfile angezeigt bekommt, dann kann ich fast sicher sein dass der Fehler nicht wirklich dort liegt, sondern irgendwo davor.

    Wenn der Fehler dagegen in meinem Code angezeigt wird, dann muss ich erstmal ausschliessen dass der Fehler wirklich dort ist wo er angezeigt wird, bevor ich anfange mir Dinge anzusehen die davor kommen.


Anmelden zum Antworten