#include Guard vs #pragma once



  • Naja, welcher große Compiler kann nicht damit umgehen, so dass man sagen kann es wäre nicht portabel? 😃



  • Butterbrot schrieb:

    #include Guards oder #pragma once?

    Ich verwende eigentlich immer ersteres, wobei ich derzeit ohnehin dazu gezwungen bin (Wenn man keine Includeguards mit exakt dem Dateinamen im C++ Builder verwendet, stellt er die Dateien nicht in Kombination dar und man kommt ggf. nur umständlich an den Inhalt).



  • Butterbrot schrieb:

    Naja, welcher große Compiler kann nicht damit umgehen, so dass man sagen kann es wäre nicht portabel? 😃

    Es ist nicht portabel, weil zB. der gcc damit nicht das macht, was du eigentlich machen möchtest.

    Dass andere Compiler nicht crashen, deine Browser-History löschen oä. macht das Beispiel noch lange nicht portabel – es passiert ja nicht das, was du haben möchtest.



  • Der GCC inkludiert die Dateien mit #pragma once nicht nur einmal, oder wie soll ich das verstehen mit dem "Es macht nicht das was du haben willst"?



  • Einfach beides verwenden, völlig standardkonform, portabel und dann gibts garantiert kein Problem...



  • pumuckl schrieb:

    Sone schrieb:

    [...]

    Du musst schon noch dazu sagen, was du mit dem Zitat jetzt aussagen willst. Ich vermute mal dass du behaupten willst, #pragma once wäre nicht standardkonform. Das wäre allerdings falsch gedacht, es ist standardkonform, aber eben nicht portabel 😉

    Nein, es ist standardkonform - es kompiliert ja!
    Es ist lediglich Implementationsspezifisch ob es ignoriert wird oder nicht.



  • Sone schrieb:

    Nein, es ist standardkonform - es kompiliert ja!
    Es ist lediglich Implementationsspezifisch ob es ignoriert wird oder nicht.

    Exakt

    Und jetzt denk drüber nach, wieso man Include Guards überhaupt verwendet... 😉



  • Da wir nun raus gefunden haben, dass #pragma once keinen großen Einfluss auf die Geschwindigkeit des Kompilierens hat(jedenfalls bei kurzen Dateien) habe ich immer noch die Frage, ob es portabel ist oder nicht?

    Nman sagt nein. Ich denke ja, wenn man nur für Windows/Linux/OSX, mit den dort gängigen Compilern entwickelt.

    Nicht portabel wäre es, in meinen Augen, wenn ich es nur unter einem System nutzen könnten, aber so wie ich es verstanden habe reicht mir ein #pragma once in den Header-Dateien und es erfüllt seinen Zweck auch für die großen Compilern auf den großen drei Systemen.



  • Butterbrot schrieb:

    Da wir nun raus gefunden haben, dass #pragma once keinen großen Einfluss auf die Geschwindigkeit des Kompilierens hat(jedenfalls bei kurzen Dateien) habe ich immer noch die Frage, ob es portabel ist oder nicht?

    Die Frage ist doch dadurch gelöst, dass es für die Geschwindigkeit nichts bringt.
    Dadurch ist klar, dass man pragma once nicht verwenden sollte.



  • Butterbrot schrieb:

    Nman sagt nein. Ich denke ja, wenn man nur für Windows/Linux/OSX, mit den dort gängigen Compilern entwickelt.

    Weil ich nicht wusste, dass die großen Compiler mittlerweile auch tatsächlich alle das richtige machen.

    Aber deine Definition von portabel ist auch interessant. Meine Programme sind alle portabel solange du auf einem 32bit WinXP SP3 entwickelst. 🤡



  • Shade Of Mine schrieb:

    Butterbrot schrieb:

    Da wir nun raus gefunden haben, dass #pragma once keinen großen Einfluss auf die Geschwindigkeit des Kompilierens hat(jedenfalls bei kurzen Dateien) habe ich immer noch die Frage, ob es portabel ist oder nicht?

    Die Frage ist doch dadurch gelöst, dass es für die Geschwindigkeit nichts bringt.
    Dadurch ist klar, dass man pragma once nicht verwenden sollte.

    Das ist falsch, es erspart dir drei Zeilen überflüssigen Includeguardcode mit eventuellen Konflikten der per define gesetzten Namen, z.B durch kopierte Headedateien für die nächste Klasse etc.

    #pragma once hat dadurch einfach mehr Vor- als Nachteile.

    nman schrieb:

    Aber deine Definition von portabel ist auch interessant. Meine Programme sind alle portabel solange du auf einem 32bit WinXP SP3 entwickelst.

    Wo habe ich das geschrieben? Wieso kann ich nicht unter Windows portable Anwendungen entwickeln?



  • Butterbrot schrieb:

    Shade Of Mine schrieb:

    Butterbrot schrieb:

    Da wir nun raus gefunden haben, dass #pragma once keinen großen Einfluss auf die Geschwindigkeit des Kompilierens hat(jedenfalls bei kurzen Dateien) habe ich immer noch die Frage, ob es portabel ist oder nicht?

    Die Frage ist doch dadurch gelöst, dass es für die Geschwindigkeit nichts bringt.
    Dadurch ist klar, dass man pragma once nicht verwenden sollte.

    Das ist falsch, es erspart dir drei Zeilen überflüssigen Includeguardcode mit eventuellen Konflikten der per define gesetzten Namen, z.B durch kopierte Headedateien für die nächste Klasse etc.

    #pragma once hat dadurch einfach mehr Vor- als Nachteile.

    Also ist es bei dir moeglich, dass es einen Konflikt bei

    #define XXX_HEADER_INCLUDED__
    

    gibt? Dann wuerde ich meinen Coding-Stil eindeutig mal ueberdenken... Ausserdem, wieso kopierst du Header-Dateien fuer die naechste Klasse? VS generiert sowieso schon Ctor und Dtor automatisch, weshalb du Klassen eh nicht so einfach kopieren kannst. Und wenn du die Eigenschaften einer anderen Klasse brauchst, dann erbe halt von ihr oder benutz sie per Komposition. Ich sehe irgendwie den Sinn hinter kompletten Header-Copy&Paste nicht. Und solltest du das wirklich kopieren wollen ist es nicht soo viel schwerer, wenn du Implementierung und Deklaration trennst, nur die Klasse zu markieren.

    Und auf die 3 Zeilen kommts nun wirklich nicht an. Ich muss sie nicht mal selber schreiben, macht schon VAX, wenn ich ihn bitte.

    Butterbrot schrieb:

    nman schrieb:

    Aber deine Definition von portabel ist auch interessant. Meine Programme sind alle portabel solange du auf einem 32bit WinXP SP3 entwickelst.

    Wo habe ich das geschrieben? Wieso kann ich nicht unter Windows portable Anwendungen entwickeln?

    Portabel heisst, dass die Anwendung so ohne Veraenderung auf allen Systemen mit jedem Standard-konformen Compiler kompiliert werden koennte. #pragma darf zwar keinen Fehler schmeissen, wenn der Compiler die Dierektive dahinter nicht kennt, aber trotzdem ist der Include-Guard-Effekt dahin. Und dann kommen die Neudeklarationen von den Typen. Boom, Compiler-Fehler.
    Natuerlich kann man nicht jede Software portabel gestalten, schon allein dadurch, dass der Standard keine GUI-Sachen, noch keine Filesystemunterstuetzung etc. hat. Aber wenn schon die Header nicht zwangslaeufig funktionieren, dann gute Nacht beim portieren.

    Es spricht ja nichts dagegen, #pragma once zu verwenden - aber dann in Verbindung mit einem Include-Guard. So kann der Compiler, sofern er es unterstuetzt, die Kompilierung an der Stelle abbrechen und fuer die, die es nicht unterstuetzen hast du trotzdem noch einen Include-Guard.



  • Ich gebe dir ja recht, dass es selten vorkommt, dass man die gleichen #defines nimmt. Wie wohl auch so viele Feinheiten von C++ selten zum tragen kommen und trotzdem bis aufs Erbrechen verteidigt werden. Warum einmal Hü und einmal Hott?

    Mit welchen Compilern funktioniert denn das #pragma once nicht wie es soll, die bei Windows, Linux und OSX nicht auf häufigsten eingesetzt werden?

    Denn wenn was auf diesen Systemen läuft, nenne ICH das portabel. Wenn man es nicht portable nennt, dann sind Qt und wxWidgets etc. auch nicht portabel.

    Wäre nett wenn wir hier mal zum Schluß kommen, ich will eigentlich coden und nicht in einem Forum rumposten. Wenn wie gesagt es nicht portabel läuft(Windows/Linux/OSX mit gängigen Compilern) dann mache ich doch beides, also pragma und guard. Wenn ich mir aber getrost jedes mal die drei Zeilen sparen kann, dann lasse ich es. Noch bin ich am Anfang meines Projektes, aber die Klassen werden von Tag zu Tag mehr und ich will da schon konsistent bleiben. Damit man zur Not mal vielleicht ein "sed script"/"Replace in Files" drüber jagen kann.



  • Warum die ganze Diskussion!? Verwendet einfach beides und die Sache ist erledigt...

    Jonas OSDever schrieb:

    #define XXX_HEADER_INCLUDED__
    

    Kleiner Hinweis dazu: Wenn du deine Include Guards so benennst, ist dein Programm streng genommen UB. Laut Standard sind alle Namen, die einen doppelten Underscore beinhalten für den Compiler reserviert. In der Praxis wirst du damit kaum Probleme haben, aber ich würd mir einfach eine bessere Namenskonvention ausdenken... 😉


  • Mod

    dot schrieb:

    Warum die ganze Diskussion!? Verwendet einfach beides und die Sache ist erledigt...

    Wie man sieht ist das sehr Microsoft spezifisch. Beim GCC war es viel schneller, wenn man pragma once nicht benutzt. Also kann man argumentieren, man solle nur ifdef benutzen.



  • Ich steh nicht so auf Warnungen, daher ifdef.



  • Kann denn keiner hier eine klare Antwort geben, ich mache das nur als Hobby und habe mir warum auch immer leider eine klare Antwort erhofft?

    Um Speed geht es schon lange nicht mehr, sondern nur darum sich immer diese drei Zeilen zu sparen, auch wenn man portabel sein will im Sinne Windows/Linux und OSX.

    Macht #pragma once unter den gängigen Compiler(VC++, GCC) für Window/Linux/OSX das gleiche, also verhindert es dass diese Datei mehr als einmal genutzt wird?

    Ja/Nein?



  • Ja

    Nur wenn du deinen Code dann mal mit einem Compiler kompilieren willst, der #pragma once nicht unterstützt, wirst du dir wünschen, dass du dir die zwei Zeilen damals nicht gespart hättest...



  • dot schrieb:

    Warum die ganze Diskussion!? Verwendet einfach beides und die Sache ist erledigt...

    Jonas OSDever schrieb:

    #define XXX_HEADER_INCLUDED__
    

    Kleiner Hinweis dazu: Wenn du deine Include Guards so benennst, ist dein Programm streng genommen UB. Laut Standard sind alle Namen, die einen doppelten Underscore beinhalten für den Compiler reserviert. In der Praxis wirst du damit kaum Probleme haben, aber ich würd mir einfach eine bessere Namenskonvention ausdenken... 😉

    Ich dachte nur, wenn am Anfang ein oder zwei Underscores am Anfang 😕
    Ok, VAX-Snippet wird geaendert (ich hab zwar zusaetzlich noch #pragma once davor gepflanzt, aber der Doppel-Underscore war glaub ich schon Default bei VAX).



  • Jonas OSDever schrieb:

    dot schrieb:

    Jonas OSDever schrieb:

    #define XXX_HEADER_INCLUDED__
    

    Kleiner Hinweis dazu: Wenn du deine Include Guards so benennst, ist dein Programm streng genommen UB. Laut Standard sind alle Namen, die einen doppelten Underscore beinhalten für den Compiler reserviert. In der Praxis wirst du damit kaum Probleme haben, aber ich würd mir einfach eine bessere Namenskonvention ausdenken... 😉

    Ich dachte nur, wenn am Anfang ein oder zwei Underscores am Anfang 😕
    Ok, VAX-Snippet wird geaendert (ich hab zwar zusaetzlich noch #pragma once davor gepflanzt, aber der Doppel-Underscore war glaub ich schon Default bei VAX).

    Jo, sowas mit double Underscores machen offenbar viele IDEs per default, es ist dennoch nicht standardkonform. Hier der entsprechende Abschnitt:

    ISO/IEC 14882:2011 §17.6.4.3.2/1 schrieb:

    Certain sets of names and function signatures are always reserved to the implementation:

    • Each name that contains a double underscore _ _ or begins with an underscore followed by an uppercase letter (2.12) is reserved to the implementation for any use.
    • Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace.

    Konservative Faustregel: Keine doppelten Underscores und keine Underscores am Anfang und du bist safe...


Anmelden zum Antworten