Ist #pragma einmal ein sicherer Include-Wächter?

Lesezeit: 7 Minuten

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


Ist pragma einmal ein sicherer Include Wachter
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


Ist pragma einmal ein sicherer Include Wachter
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.

Ich habe das auch gefunden, zumindest auf GCC, es erkennt den Standard an #ifndef Guard einbinden und optimiertalso sollte es nicht viel langsamer sein als #pragma once.

  • 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)

    – Andrej

    3. März 2011 um 21:57 Uhr

  • GCC-Dokumentation zur Guard-Makro-Optimierung: gcc.gnu.org/onlinedocs/cppinternals/Guard-Macros.html

    – Adrian

    17. Mai 2011 um 15:31 Uhr

  • 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

1647060011 895 Ist pragma einmal ein sicherer Include Wachter
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

#ifndef HEADERNAME_H
#define HEADERNAME_H
...
#endif

Es erledigt die gleiche Aufgabe und füllt den Präprozessor nicht mit zusätzlichen Makros.

GCC unterstützt #pragma once offiziell ab Version 3.4.

GCC unterstützt #pragma once seit 3.4, siehe http://en.wikipedia.org/wiki/Pragma_once für weitere Compiler-Unterstützung.

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.

Ist pragma einmal ein sicherer Include Wachter
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.

1647060012 919 Ist pragma einmal ein sicherer Include Wachter
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

992690cookie-checkIst #pragma einmal ein sicherer Include-Wächter?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy