Eine Schwierigkeit beim automatischen Ausschluss von Duplikat-Headern besteht darin, dass der C-Standard bezüglich der Bedeutung von Include-Dateinamen relativ leise ist. Angenommen, die zu kompilierende Hauptdatei enthält Direktiven #include "f1.h"
und #include "f2.h"
, und die für diese Direktiven gefundenen Dateien enthalten beide Direktiven #include "f3.h"
. Wenn f1.h
und f2.h
sich in verschiedenen Verzeichnissen befinden, die jedoch durch die Suche nach Include-Pfaden gefunden wurden, ist unklar, welche #include
Anweisungen in diesen Dateien zum Laden derselben f3.h
oder verschiedener Dateien vorgesehen sind.
Noch schlimmer wird es, wenn man die Möglichkeiten von Include-Dateien einschließlich relativer Pfade hinzufügt. In einigen Fällen, in denen Header-Dateien relative Pfade für verschachtelte Include-Anweisungen verwenden und Änderungen an bereitgestellten Header-Dateien vermieden werden sollen, kann es erforderlich sein, eine Header-Datei an mehreren Stellen in der Verzeichnisstruktur eines Projekts zu duplizieren. Obwohl mehrere physische Kopien dieser Headerdatei vorhanden sind, sollten sie semantisch als eine einzelne Datei betrachtet werden.
Wenn die #pragma once
Direktive zulässt, dass ein Bezeichner once
mit der Semantik folgt , dass der Compiler die Datei überspringen soll, wenn der Bezeichner mit einer von einer zuvor angetroffenen #pragma once
Direktive übereinstimmt , ist die Semantik eindeutig. Ein Compiler, der erkennen konnte, dass eine #include
Direktive dieselbe #pragma once
Datei mit denselben Tags wie eine frühere lädt, konnte durch Überspringen der Datei ein wenig Zeit sparen, ohne sie erneut zu öffnen, aber eine solche Erkennung wäre semantisch nicht wichtig, da die Datei übersprungen würde, ob oder nicht, der Dateiname wurde als Übereinstimmung erkannt. Es sind mir jedoch keine Compiler bekannt, die auf diese Weise arbeiten. Wenn Sie einen Compiler haben, prüfen Sie, ob eine Datei mit dem Muster übereinstimmt, #ifndef someIdentifier / #define someIdentifier / #endif [for that ifndef] / nothing following
und behandeln Sie so etwas als äquivalent zu obigem #pragma once someIdentifier
ifsomeIdentifier
bleibt definiert, ist im wesentlichen so gut.
#pragma once
Befehl, der den Compiler anweist, diese Datei nur einmal einzuschließen.