Includes in cpp Datei verlagern



  • @Th69 sagte in Includes in cpp Datei verlagern:

    Es würde ja auch reichen, eine Header-Datei mit den Vorwärtsdeklarationen zu erstellen ("qt-forward.h").
    Es gibt extra (dafür) die Makros: QT_FORWARD_DECLARE_CLASS sowie QT_BEGIN_NAMESPACE/QT_END_NAMESPACE.

    Mein erster Ansatz war jetzt, für jeden Header spezifisch zu forwarden.
    Du meinst das aber jetzt sicher so, dass man sich genau einen Header mit forwards macht und den überall in Headern includet? Forwards fressen ja an sich kein Brot, denke ich mal, daher könnte das tatsächlich gehen, auch wenn natürlich immer welche dabei sind, die in einem Header unnütz sind.



  • Ja, genau so meinte ich es. Der Aufwand bei jedem Header explizit die Vorwärtsdeklarationen zu erstellen ist größer als einfach nur jeweils #include "qt-forward.h" zu benutzen.
    Wenn man dann in einem großen Projekt doch Hunderte von Vorwärtsdeklarationen (für fast alle Qt-Widgets und -Klassen) benutzt, dann kann man immer noch diese aufteilen.



  • Ich bin gerade dabei, mein altes QT-Projekt umzustrukturieren. Es ist jedenfalls ne Menge Arbeit und der Compiler wirft einem ein paar Steine in den Weg 😉

    Wo forwards in einem Header nicht eingesetzt werden können:

    • Basisklassen ( Klassen von denen ich ableite )
    • Member die als Instanz vorliegen und nicht als Pointer
    • enums kann man nicht forwarden

    Probleme die bei mir bisher aufgetreten sind ( nicht allgemeingültig ):

    • komplexere typedefs ( z.B. typedef std::shared_ptr<MyClass> MyOftenUsedPointer; ). Solche typedefs benötigen noch für ihre eigene Existenz mindestens zwei Header. Diese typedefs muss man einer geeigneten Stelle platzieren.
    • Enums die im public-Teil einer Klasse definiert werden und in einer anderen Klasse im Header benötigt werden.

    Für das Enumproblem fällt mir aktuell keine gescheite Lösung ein, außer jedes Enum in einen eigenen Header zu verfrachten, oder einen Sammelheader für Enums zu machen. Die zweite Lösung ist eher unschön, weil enums mitunter Klassenspezifisch sind und zu einer Klasse gehören. Die erste Lösung ist ne Menge Aufwand und produziert jede Menge Header.

    Besonders nervig sind Enums, die in einem externen Modul innerhalb einer Klasse definiert sind, weil man auf dieses Modul quasi keinen Einfluss hat, man die Definition des Enums aber für die eigenen KlassenDefintion benötigt.

    Eine Idee wäre, die externen Module/Klassen generell nicht zu forwarden, sondern in einen pch zu verschieben.



  • Ich habe für ein embedded Projekt die Include Bäume extrahiert (als Teil von compile time optimization) und dann zeichnen lassen.
    Die generierten SVG Dateien wurden teilweise wahnwitzig riesig, und das allein durch ein paar boost header. Und das bei den kleinen Dateien, wo nicht viel included wird, die großen konnte ich gar nicht mehr zeichnen.
    Also ja, ein "harmloser" include kann zu einem wahren Monstrum werden.
    Also am besten so viel in Sourcen ziehen wie es geht.

    Ein "harmloses" Beispiel



  • @5cript sagte in Includes in cpp Datei verlagern:

    Also am besten so viel in Sourcen ziehen wie es geht.

    Das ist schon klar. Nur ist halt das Problem, dass man auf einige include-header in der header Datei nicht verzichten kann...



  • @It0101 sagte in Includes in cpp Datei verlagern:

    @5cript sagte in Includes in cpp Datei verlagern:

    Also am besten so viel in Sourcen ziehen wie es geht.

    Das ist schon klar. Nur ist halt das Problem, dass man auf einige include-header in der header Datei nicht verzichten kann...

    Ich möchte nur unterstreichen, dass man oft sich gar nicht ausmalt was ein Präprozessor und Compiler leistet und was man seiner armen Toolchain antut.



  • @5cript sagte in Includes in cpp Datei verlagern:

    @It0101 sagte in Includes in cpp Datei verlagern:

    @5cript sagte in Includes in cpp Datei verlagern:

    Also am besten so viel in Sourcen ziehen wie es geht.

    Das ist schon klar. Nur ist halt das Problem, dass man auf einige include-header in der header Datei nicht verzichten kann...

    Ich möchte nur unterstreichen, dass man oft sich gar nicht ausmalt was ein Präprozessor und Compiler leistet und was man seiner armen Toolchain antut.

    Das sollte mal als Hinweis in jede IDE eingebaut werden 😉



  • @5cript sagte in Includes in cpp Datei verlagern:

    ein paar boost header

    Ja, sind bei uns auch stets der Compile-time-killer.
    Haben sogar Klassen um-designed, um boost aus headern rauszukriegen.



  • @It0101 sagte in Includes in cpp Datei verlagern:

    enums kann man nicht forwarden

    AFAIK kann man enums forwarden, wenn der underlying type explizit angegeben wird:

    enum Foo : int;
    


  • @LeMace sagte in Includes in cpp Datei verlagern:

    @It0101 sagte in Includes in cpp Datei verlagern:

    enums kann man nicht forwarden

    AFAIK kann man enums forwarden, wenn der underlying type explizit angegeben wird:

    enum Foo : int;
    

    Ok, das war mir nicht bekannt. Guter Hinweis.



  • @5cript sagte in Includes in cpp Datei verlagern:

    Ich möchte nur unterstreichen, dass man oft sich gar nicht ausmalt was ein Präprozessor und Compiler leistet und was man seiner armen Toolchain antut.

    Habe mir auch schon oft gedacht, ob es wirklich sinnvoll ist, wenn Build-Systeme für jede Übersetzungseinheit einen neuen Compiler-Prozess starten, der nichts von dem weiss, was vorher gewesen ist.

    Ich frage mich, warum wir nach all der Zeit nicht schon Toolchains haben, bei denen der oder die Compiler-Prozesse einmal gestartet, und dann vom Build-System "ferngesteuert" werden, so dass diese einmal verarbeitete Header wiederverwenden können.Das wäre natürlich ein deutlich komplexeres System, aber die Geschwindigkeitsvorteile könnten enorm sein. Precompiled Header sind zwar auch eine Lösung, erfordern aber meist Anpassungen am Code und müssen auch für jede Übersetzungseinheit zumindest "geladen" werden.

    Oder gibt es sowas in die Richtung vielleicht sogar schon? ist mir zumindest bisher noch nicht aufgefallen, so wie die Build-Systeme, die ich kenne funktionieren.



  • @Finnegan
    Mit dem precompiled-header hab ich vorhin gerade rumexperimentiert. Was die Compilezeitoptimierung angeht ist das echt eine Gratwanderung. Da ist es entscheidend ob man diesen oder jenen Header noch mit reinnimmt oder ihn weglässt.

    Mich würde interessieren, ob es eine Art "CheckListe" gibt, wie Quellcode strukturiert sein muss, damit die Compilezeit einigermaßen optimal ist.

    @Leon0402 das mit dem konsequenten forwarden ( soweit möglich ) hat übrigens kaum Unterschied in der Compilezeit gemacht. Vermutlich weil es einfach zuviele Ausnahmen gibt, bei denen das nicht geht.


Log in to reply