Include Guard für jedes gesamte hpp?


  • Mod

    Doppelt bringt doch nichts, wenn der Vorteil doch geringere Schreibarbeit ist. Wenn du auf 100% sicher gehen willst, dass das auch auf einem C64 compiliert, dann nimm Includeguards. Wenn du 99% sicher sein willst, und ein paar Zeichen weniger schreiben möchtest (und Szenarien verhindern möchtest, wo du dich vertippst, oder jemand anderes den gleichen Identifier benutzt hat), nimm pragma once.



  • ChatGPT 3.5 (13.05.2024):

    Beide Methoden, #pragma once und Include Guards, dienen dazu, sicherzustellen, dass Header-Dateien nur einmal in einem Übersetzungsunit eingefügt werden. Es gibt jedoch einige Unterschiede zwischen den beiden Ansätzen:

    #pragma once:

    Es ist ein Compiler-spezifisches Feature und möglicherweise nicht portabel über verschiedene Compiler hinweg.
    Es ist einfacher zu verwenden, da Sie keine speziellen Makros definieren müssen.
    Es kann zu schnelleren Kompilierzeiten führen, da der Compiler feststellen kann, ob die Datei bereits eingeschlossen wurde, ohne nach vorherigen Einbeziehungen zu suchen.

    Include Guards:

    Sie sind portabler, da sie von allen C++-Compilern unterstützt werden.
    Sie erfordern das Definieren spezieller Makros, was etwas mehr Schreibarbeit bedeutet.
    Sie können dazu beitragen, Konflikte zu vermeiden, wenn mehrere Header-Dateien in einem Projekt den gleichen Dateinamen haben.
    Insgesamt ist die Wahl zwischen #pragma once und Include Guards oft eine Frage der persönlichen Präferenz und der spezifischen Anforderungen des Projekts. Einige Entwickler bevorzugen #pragma once wegen seiner Einfachheit, während andere sich für Include Guards entscheiden, weil sie portabler sind. In vielen modernen C++-Projekten wird #pragma once aufgrund seiner Einfachheit und Effizienz jedoch häufig verwendet.



  • #pragma once löst auch noch das Problem doppelter Include-Guard-Namen. Wenn man viele 3rd Party Bibliotheken einsetzt kann es vorkommen, dass in verschiedenen .h Dateien der gleiche Include-Guard-Name benutzt wird, was zu üblen Fehlern führen kann. Das Problem hat man mit #pragma once nicht mehr.


  • Mod

    @DocShoe sagte in Include Guard für jedes gesamte hpp?:

    #pragma once löst auch noch das Problem doppelter Include-Guard-Namen. Wenn man viele 3rd Party Bibliotheken einsetzt kann es vorkommen, dass in verschiedenen .h Dateien der gleiche Include-Guard-Name benutzt wird, was zu üblen Fehlern führen kann. Das Problem hat man mit #pragma once nicht mehr.

    Aber das umgekehrte Problem, dass manche Leute die schlechte Angewohnheit haben, abhängige Header zu kopieren oder zu linken, anstatt sich um korrekte Installation und Includeverzeichnisse zu kümmern. Dann würde der Includeguard greifen, aber nicht das Pragma. Wenn man nur lange genug sucht, findet man immer ein Argument für oder gegen jede der Seiten. In jedem normalen Projekt mit normalen Best Practices wird aber keiner dieser Unterschiede eine Rolle spielen.



  • Die Diskussion ist hoffentlich bald akademisch, wenn Module korrekt von den Compilern unterstützt werden.



  • MMn. kann man problem- und gefahrlos #pragma once verwenden.

    Im schlimmsten Fall muss man sich beim Compilerwechsel ein kleines Tool schreiben, das die #pragma once in normale Include-Guards umwandelt. Sollte keine Hexerei sein. Die Guard-Namen kann man dabei z.B. leicht aus GUIDs generieren. Bzw. es ist leicht möglich dass es schon fertige Tools gibt die das können - vielleicht kann es sogar Clang-Tidy. Damit kann man dann hunderte oder tausende Sourcefiles ohne grossen Aufwand umstellen wenn nötig.



  • @john-0 sagte in Include Guard für jedes gesamte hpp?:

    Die Diskussion ist hoffentlich bald akademisch, wenn Module korrekt von den Compilern unterstützt werden.

    Ja, kommt sicher bald 🙂



  • Wir benutzen das Embarcadero RAD Studio (ganz früher Borland), bei dem Include-Guards eine weitere Funktion erfüllen:
    Die Guards müssen einem Namensschema folgen, nur dann kann die IDE den Bezug der Dateien untereinander herstellen. Der Guard der Datei foo.h muss FooH lauten, ansonsten findet die IDE die zugehörige .cpp (oder .dfm) Datei nicht. Somit hat man nicht immer die freie Wahl des Namens, was in diesem Fall eine ziemlich bescheuerte Idee seitens Borlands war.


  • Mod

    @Tyrdal sagte in Include Guard für jedes gesamte hpp?:

    @john-0 sagte in Include Guard für jedes gesamte hpp?:

    Die Diskussion ist hoffentlich bald akademisch, wenn Module korrekt von den Compilern unterstützt werden.

    Ja, kommt sicher bald 🙂

    Ach, die jüngeren wissen gar nicht, wie gut C++ es heute hat. Alle 3 Jahre neue Features, die auch halbwegs schnell umgesetzt werden? Wohingegen mein Code von 2010 wahrscheinlich auf einem Compiler aus den 1990ern compiliert hätte - und das lag nicht an mir.



  • @SeppJ sagte in Include Guard für jedes gesamte hpp?:

    Ach, die jüngeren wissen gar nicht, wie gut C++ es heute hat. Alle 3 Jahre neue Features, die auch halbwegs schnell umgesetzt werden? Wohingegen mein Code von 2010 wahrscheinlich auf einem Compiler aus den 1990ern compiliert hätte - und das lag nicht an mir.

    Die Prä-ISO-Norm Standard Library funktioniert zum Teil deutlich anders als die ISO-Norm Standard Library, weshalb auch die Header mit .h rausgeworfen wurden, und die ohne Dateiendung kamen. Dann gab es eine starke Änderung bei den String Streams, weshalb die aktuellen Header stringstreams und die alten strstreams existieren, und dann gab es noch eine Variante mit .h am Ende.


Anmelden zum Antworten