Ich habe gelesen, dass es einige Compiler-Optimierungen bei der Verwendung gibt #pragma once was zu einer schnelleren Kompilierung führen kann. Ich erkenne an, dass dies kein Standard ist und daher ein plattformübergreifendes Kompatibilitätsproblem darstellen könnte.
Wird dies von den meisten modernen Compilern auf Nicht-Windows-Plattformen (gcc) unterstützt?
Ich möchte Probleme mit der Plattformkompilierung vermeiden, aber auch die zusätzliche Arbeit von Fallback Guards vermeiden:
#pragma once
#ifndef HEADER_H
#define HEADER_H
...
#endif // HEADER_H
Sollte ich besorgt sein? Soll ich dafür weitere mentale Energie aufwenden?
Nachdem ich eine ähnliche Frage gestellt hatte, fand ich das heraus #pragma once scheint einige Probleme mit der Klassenansicht in VS 2008 zu vermeiden. Ich bin dabei, Include Guards loszuwerden und sie alle durch zu ersetzen #pragma once deshalb.
– SmacL
2. Februar 2011 um 13:54 Uhr
Motti
#pragma once hat einen Nachteil (abgesehen davon, dass sie nicht dem Standard entspricht) und das heißt, wenn Sie dieselbe Datei an verschiedenen Orten haben (wir haben dies, weil unser Build-System Dateien herumkopiert), dann wird der Compiler denken, dass dies unterschiedliche Dateien sind.
Sie können aber auch zwei Dateien mit demselben Namen an verschiedenen Orten haben, ohne sich die Mühe machen zu müssen, verschiedene #define NAMES zu erstellen, die in Form von HEADERFILENAME_H vorliegen
– Varga
30. Juli 2010 um 12:39 Uhr
Sie können auch zwei oder mehr Dateien mit demselben #define WHATEVER haben, was unendlich viel Spaß macht, weshalb ich pragma einmal bevorzugen würde.
– Chris Huang-Leaver
21. September 2011 um 14:52 Uhr
Nicht überzeugend … Ändern Sie das Build-System zu einem System, das keine Dateien herumkopiert, sondern stattdessen symbolische Links verwendet, oder fügen Sie dieselbe Datei nur von einem Ort in jede Übersetzungseinheit ein. Klingt eher so, als wäre Ihre Infrastruktur ein Durcheinander, das neu organisiert werden muss.
– Jakow Galka
11. Mai 2012 um 19:04 Uhr
Und wenn Sie verschiedene Dateien mit demselben Namen in verschiedenen Verzeichnissen haben, wird der #ifdef-Ansatz davon ausgehen, dass es sich um dieselbe Datei handelt. Es gibt also einen Nachteil für den einen und einen Nachteil für den anderen.
– Rxantos
24. April 2014 um 4:50 Uhr
@rxantos, falls sich die Dateien unterscheiden #ifdef Makrowert kann auch abweichen.
– Motti
24. April 2014 um 6:59 Uhr
Zifre
Verwenden #pragma once sollte auf jedem modernen Compiler funktionieren, aber ich sehe keinen Grund, keinen Standard zu verwenden #ifndef Wächter beinhalten. Es funktioniert gut. Die einzige Einschränkung ist, dass GCC nicht unterstützt wurde #pragma once Vor Version 3.4.
Es sollte überhaupt nicht langsamer sein (mit GCC sowieso).
– Jason Coco
24. April 2009 um 21:07 Uhr
Es ist nicht so implementiert. Wenn die Datei stattdessen das erste Mal mit einem #ifndef beginnt und mit einem #endif endet, erinnert sich gcc daran und überspringt dieses Include in Zukunft immer, ohne sich die Mühe zu machen, die Datei zu öffnen.
– Jason Coco
25. April 2009 um 1:32 Uhr
#pragma once ist im Allgemeinen schneller, da die Datei nicht vorverarbeitet wird. ifndef/define/endif erfordert sowieso eine Vorverarbeitung, da Sie nach diesem Block etwas Kompilierbares haben können (theoretisch)
Um Include Guards verwenden zu können, müssen Sie zusätzlich ein neues Symbol definieren, z #ifndef FOO_BAR_H, normalerweise für eine Datei wie “foo_bar.h”. Wenn Sie diese Datei später umbenennen, sollten Sie die Include-Wächter entsprechend anpassen, um mit dieser Konvention übereinzustimmen? Auch wenn Sie zwei unterschiedliche foo_bar.hs an zwei verschiedenen Stellen in Ihrem Codebaum haben, müssen Sie sich zwei verschiedene Symbole für jedes einfallen lassen. Kurze Antwort ist zu verwenden #pragma once und wenn Sie wirklich in einer Umgebung kompilieren müssen, die dies nicht unterstützt, dann fahren Sie fort und fügen Sie include guards für diese Umgebung hinzu.
– Brandin
22. Juni 2014 um 7:45 Uhr
Ich wünsche #pragma once (oder so ähnlich) im Standard gewesen. Wachen einbeziehen ist keine wirklich große Sache (aber sie scheinen Leuten, die die Sprache lernen, etwas schwer zu erklären zu sein), aber es scheint ein kleiner Ärger zu sein, der hätte vermieden werden können.
In der Tat, seit 99,98 % der Zeit, die #pragma once Behavior das gewünschte Verhalten ist, wäre es schön gewesen, wenn das Verhindern des mehrfachen Einschließens eines Headers automatisch vom Compiler gehandhabt würde, mit a #pragma oder etwas, um doppeltes Einschließen zu ermöglichen.
Aber wir haben, was wir haben (außer dass Sie vielleicht nicht haben #pragma once).
Was ich wirklich will, ist ein Standard #import Richtlinie.
– John
19. Juli 2013 um 15:21 Uhr
Eine Standard-Einfuhrrichtlinie kommt: isocpp.org/blog/2012/11/… Aber noch nicht hier. Ich unterstütze sie nachdrücklich.
– AHilfe
3. April 2015 um 18:34 Uhr
@AHelps Vaporware. Ist das jetzt fast fünf Jahre her. Vielleicht kommst du 2023 auf diesen Kommentar zurück und sagst „Ich habe es dir doch gesagt“.
– doug65536
10. Dezember 2016 um 10:28 Uhr
Sollte es in C++20 schaffen.
– Ionoklast Brigham
2. September 2017 um 4:22 Uhr
… und hat es in C++20 geschafft.
– LNJ
29. Juni 2020 um 9:02 Uhr
JaredPar
Ich kenne keine Leistungsvorteile, aber es funktioniert auf jeden Fall. Ich verwende es in allen meinen C++-Projekten (vorausgesetzt, ich verwende den MS-Compiler). Ich finde es effektiver als zu verwenden
Der große Vorteil sehe ich bei der Verwendung #pragma once Im Gegensatz zum Einschließen von Wächtern sollen Kopier-/Einfügefehler vermieden werden.
Seien wir ehrlich: Die meisten von uns beginnen kaum eine neue Header-Datei von Grund auf neu, sondern kopieren einfach eine vorhandene und modifizieren sie nach unseren Bedürfnissen. Es ist viel einfacher, eine Arbeitsvorlage mit zu erstellen #pragma once statt Wachen einschließen. Je weniger ich die Vorlage ändern muss, desto weniger Fehler werden wahrscheinlich auftreten. Den gleichen Include-Wächter in verschiedenen Dateien zu haben, führt zu seltsamen Compiler-Fehlern und es dauert einige Zeit, um herauszufinden, was schief gelaufen ist.
TL;DR: #pragma once ist einfacher zu bedienen.
Edwin Jarvis
Ich benutze es und bin zufrieden damit, da ich viel weniger tippen muss, um einen neuen Header zu erstellen. Es hat bei mir auf drei Plattformen gut funktioniert: Windows, Mac und Linux.
Ich habe keine Leistungsinformationen, aber ich glaube, dass der Unterschied zwischen #pragma und dem Include-Wächter nichts im Vergleich zur Langsamkeit beim Analysieren der C++-Grammatik sein wird. Das ist das eigentliche Problem. Versuchen Sie, die gleiche Anzahl von Dateien und Zeilen beispielsweise mit einem C#-Compiler zu kompilieren, um den Unterschied zu sehen.
Am Ende spielt es keine Rolle, ob Sie den Wächter oder das Pragma verwenden.
Jess Beder
Mit ‘#pragma once‘ hat möglicherweise keine Wirkung (es wird nicht überall unterstützt – obwohl es zunehmend weit verbreitet ist), also müssen Sie trotzdem den bedingten Kompilierungscode verwenden. Warum sollten Sie sich in diesem Fall mit ‘#pragma once‘? Der Compiler optimiert es wahrscheinlich sowieso. Es hängt jedoch von Ihren Zielplattformen ab. Wenn alle Ihre Ziele es unterstützen, dann fahren Sie fort und verwenden Sie es – aber es sollte eine bewusste Entscheidung sein, denn die Hölle bricht los, wenn Sie nur das Pragma verwenden und dann auf einen Compiler portieren, der es nicht unterstützt.
Ich bin nicht der Meinung, dass Sie Wachen sowieso unterstützen müssen. Wenn Sie einmal #pragma (oder Guards) verwenden, liegt dies daran, dass es ohne sie zu Konflikten kommt. Wenn es also von Ihrem Chain-Tool nicht unterstützt wird, wird das Projekt einfach nicht kompiliert, und Sie befinden sich in genau der gleichen Situation, als wenn Sie Ansi C auf einem alten K&R-Compiler kompilieren möchten. Sie müssen nur ein aktuelleres Kettenwerkzeug besorgen oder den Code ändern, um einige Schutzvorrichtungen hinzuzufügen. All the hellbreaking wäre, wenn das Programm zwar kompiliert, aber nicht funktioniert.
– kriss
21. Juli 2016 um 16:56 Uhr
9926900cookie-checkIst #pragma einmal ein sicherer Include-Wächter?yes
Nachdem ich eine ähnliche Frage gestellt hatte, fand ich das heraus
#pragma once
scheint einige Probleme mit der Klassenansicht in VS 2008 zu vermeiden. Ich bin dabei, Include Guards loszuwerden und sie alle durch zu ersetzen#pragma once
deshalb.– SmacL
2. Februar 2011 um 13:54 Uhr