Traditionell war / ist die standardmäßige und tragbare Methode zur Vermeidung mehrerer Header-Einschlüsse in C ++ die Verwendung des #ifndef - #define - #endif
Pre-Compiler-Direktiven-Schemas, das auch als Makro-Guard-Schema bezeichnet wird (siehe Code-Snippet unten).
#ifndef MY_HEADER_HPP
#define MY_HEADER_HPP
...
#endif
In den meisten Implementierungen / Compilern (siehe Bild unten) gibt es jedoch eine "elegantere" Alternative, die denselben Zweck erfüllt wie das aufgerufene Makro-Guard-Schema #pragma once
. #pragma once
hat im Vergleich zum Makro-Guard-Schema mehrere Vorteile, darunter weniger Code, die Vermeidung von Namenskonflikten und manchmal eine verbesserte Kompilierungsgeschwindigkeit.
Bei einigen Nachforschungen stellte ich fest, dass die #pragma once
Direktive zwar von fast allen bekannten Compilern unterstützt wird, es jedoch eine Unklarheit darüber gibt, ob die #pragma once
Direktive Teil des C ++ 11-Standards ist oder nicht.
Fragen:
- Könnte jemand klären, ob die
#pragma once
Direktive Teil des C ++ 11-Standards ist oder nicht? - Wenn es nicht Teil des C ++ 11-Standards ist, gibt es Pläne, es in späteren Versionen (z. B. C ++ 14 oder höher) aufzunehmen?
- Es wäre auch schön, wenn jemand die Vor- und Nachteile bei der Verwendung einer der beiden Techniken (dh Makroschutz gegenüber
#pragma once
) weiter erläutern könnte .
#pragma once
normalerweise nicht.Antworten:
#pragma once
ist nicht Standard. Es ist eine weit verbreitete (aber nicht universelle) Erweiterung, die verwendet werden kannEs wurde für die Standardisierung in Betracht gezogen, aber abgelehnt, da es nicht zuverlässig implementiert werden kann. (Die Probleme treten auf, wenn Sie über Dateien verfügen, auf die über verschiedene Remote-Bereitstellungen zugegriffen werden kann.)
Es ist ziemlich einfach sicherzustellen, dass es innerhalb einer einzelnen Entwicklung keine Include-Guard-Konflikte gibt. Für Bibliotheken, die von vielen verschiedenen Entwicklungen verwendet werden können, besteht die offensichtliche Lösung darin, beim Erstellen viele zufällige Zeichen für den Include Guard zu generieren. (Ein guter Editor kann eingerichtet werden, um dies für Sie zu tun, wenn Sie einen neuen Header öffnen.) Aber auch ohne dies habe ich noch keine Probleme mit Konflikten zwischen Bibliotheken.
quelle
pragma once
etwas, das von Natur aus nicht portabel ist (und nicht einmal in Betracht gezogen werden sollte) , nicht portabel implementiert werden kann, ein weiterer Unsinn der verkehrten C ++ - Welt.#include
dies entfernt werden muss, da man die Direktive blind missbrauchen kann.#pragma once
schränkt die Portabilität in keiner Weise ein, vorausgesetzt, Sie nutzen keine symbolischen Links, um die Kompilierung zu unterbrechen.Abschnitt §16.6 des Standards ( Entwurf N3936 ) beschreibt
#pragma
Richtlinien wie folgt :Grundsätzlich
#pragma once
handelt es sich um eine implementierungsspezifische Instanz einer#pragma
Direktive, und nein, sie ist kein Standard. Noch.Es wird häufig von den meisten "großen Compilern", einschließlich GCC und Clang, weitgehend unterstützt und wird daher manchmal empfohlen, um das Boilerplate von Include-Guards zu vermeiden.
quelle
#pragma
und#define
Header-Guard können.#define
Header-Guard schreibt , hat er / sie KEINEN Grund, ebenfalls zu schreiben#pragma once
.#pragma once
d war, und im Falle, dass es#include
wieder d ist, kann er das überspringen#include
(nicht einmal die Datei öffnen). gcc macht dasselbe mit Header Guards, aber es ist sehr, sehr zerbrechlich. Der#pragma
eine ist einfach zu machen, der Kopfschutz ist schwer.