Einbeziehung von Quelldateien
Bindet andere Quelldateien in die aktuelle Quelldatei unmittelbar nach der Direktive ein.
Inhalt |
[bearbeiten] Syntax
#include < h-char-sequence > new-line |
(1) | ||||||||
#include " q-char-sequence " new-line |
(2) | ||||||||
#include pp-tokens new-line |
(3) | ||||||||
__has_include ( " q-char-sequence " )__has_include ( < h-char-sequence > ) |
(4) | (seit C++17) | |||||||
__has_include ( string-literal )__has_include ( < h-pp-tokens > ) |
(5) | (seit C++17) | |||||||
| new-line | - | Das Zeilenumbruchzeichen |
| h-char-sequence | - | Eine Sequenz von einem oder mehreren h-chars, wobei das Auftreten der folgenden Elemente bedingt unterstützt wird und Implementierungs-definierte Semantik hat:
|
| h-char | - | Jedes Mitglied des Quellzeichensatzes(bis C++23)Übersetzungszeichensatzes(seit C++23) außer Zeilenumbruch und > |
| q-char-sequence | - | Eine Sequenz von einem oder mehreren q-chars, wobei das Auftreten der folgenden Elemente bedingt unterstützt wird und Implementierungs-definierte Semantik hat:
|
| q-char | - | Jedes Mitglied des Quellzeichensatzes(bis C++23)Übersetzungszeichensatzes(seit C++23) außer Zeilenumbruch und " |
| pp-tokens | - | Eine Sequenz von einem oder mehreren Präprozessor-Tokens |
| string-literal | - | Ein String-Literal |
| h-pp-tokens | - | Eine Sequenz von einem oder mehreren Präprozessor-Tokens außer > |
[bearbeiten] Erklärung
include in der Direktive werden wie in normalem Text verarbeitet (d.h. jeder als Makroname definierte Bezeichner wird durch seine Ersetzungsliste von Präprozessor-Tokens ersetzt). Wenn die Direktive nach allen Ersetzungen eine der beiden vorherigen Formen nicht übereinstimmt, ist das Verhalten undefiniert. Die Methode, mit der eine Sequenz von Präprozessor-Tokens zwischen einem Präprozessor-Token-Paar < und > oder einem Paar von " Zeichen in ein einzelnes Header-Name-Präprozessor-Token kombiniert wird, ist Implementierungs-definiert.#include Direktive nicht erfüllen würde, ist das Programm fehlerhaft. Der Ausdruck __has_include ergibt 1, wenn die Suche nach der Quelldatei erfolgreich ist, und 0, wenn die Suche fehlschlägt.|
Wenn der durch den header-name (d.h.
|
(seit C++20) |
__has_include kann im Ausdruck von #if und #elif erweitert werden. Es wird von #ifdef, #ifndef, #elifdef, #elifndef(seit C++23) und defined als definiertes Makro behandelt, kann aber nirgendwo sonst verwendet werden.
[bearbeiten] Anmerkungen
Typische Implementierungen suchen nur in Standard-Include-Verzeichnissen für die Syntax (1). Die Standard-C++-Bibliothek und die Standard-C-Bibliothek sind implizit in diesen Standard-Include-Verzeichnissen enthalten. Die Standard-Include-Verzeichnisse können normalerweise vom Benutzer über Compiler-Optionen gesteuert werden.
Die Absicht der Syntax (2) ist es, nach Dateien zu suchen, die nicht von der Implementierung gesteuert werden. Typische Implementierungen suchen zuerst im Verzeichnis, in dem sich die aktuelle Datei befindet, und greifen dann auf (1) zurück.
Wenn eine Datei eingebunden wird, wird sie durch die Übersetzungsphasen 1-4 verarbeitet, was rekursiv die Erweiterung verschachtelter #include Direktiven bis zu einer Implementierungs-definierten Verschachtelungsgrenze beinhalten kann. Um wiederholte Einbindungen derselben Datei und endlose Rekursion zu vermeiden, wenn eine Datei sich selbst einbindet, vielleicht transitiv, werden *Header Guards* üblicherweise verwendet: der gesamte Header wird umschlossen in
#ifndef FOO_H_INCLUDED /* any name uniquely mapped to file name */ #define FOO_H_INCLUDED // contents of the file are here #endif
Viele Compiler implementieren auch das nicht-standardmäßige pragma #pragma once mit ähnlichen Effekten: es deaktiviert die Verarbeitung einer Datei, wenn dieselbe Datei (wobei die Dateiidentität OS-spezifisch bestimmt wird) bereits eingebunden wurde.
Eine Zeichensequenz, die wie eine Escape-Sequenz in q-char-sequence oder h-char-sequence aussieht, kann je nach Implementierung zu einem Fehler führen, als das Zeichen interpretiert werden, das der Escape-Sequenz entspricht, oder eine völlig andere Bedeutung haben.
Ein Ergebnis von __has_include von 1 bedeutet nur, dass eine Header- oder Quelldatei mit dem angegebenen Namen existiert. Es bedeutet nicht, dass die Header- oder Quelldatei beim Einbinden keinen Fehler verursacht oder etwas Nützliches enthält. Zum Beispiel kann auf einer C++-Implementierung, die sowohl C++14- als auch C++17-Modi unterstützt (und __has_include in ihrem C++14-Modus als konforme Erweiterung bereitstellt), __has_include(<optional>) im C++14-Modus 1 sein, aber tatsächlich kann #include <optional> einen Fehler verursachen.
[bearbeiten] Beispiel
#if __has_include(<optional>) #include <optional> #define has_optional 1 template<class T> using optional_t = std::optional<T>; #elif __has_include(<experimental/optional>) #include <experimental/optional> #define has_optional -1 template<class T> using optional_t = std::experimental::optional<T>; #else #define has_optional 0 template<class V> class optional_t { V v{}; bool has{}; public: optional_t() = default; optional_t(V&& v) : v(v), has{true} {} V value_or(V&& alt) const& { return has ? v : alt; } // etc. }; #endif #include <iostream> int main() { if (has_optional > 0) std::cout << "<optional> is present\n"; else if (has_optional < 0) std::cout << "<experimental/optional> is present\n"; else std::cout << "<optional> is not present\n"; optional_t<int> op; std::cout << "op = " << op.value_or(-1) << '\n'; op = 42; std::cout << "op = " << op.value_or(-1) << '\n'; }
Ausgabe
<optional> is present op = -1 op = 42
[bearbeiten] Fehlerberichte
Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | angewendet auf | Verhalten wie veröffentlicht | Korrigiertes Verhalten |
|---|---|---|---|
| CWG 787 | C++98 | das Verhalten ist undefiniert, wenn eine Escape-Sequenz in q-char-sequence oder h-char-sequence vorkommt |
es ist bedingt unterstützt |
[bearbeiten] Siehe auch
| Eine Liste der Header-Dateien der C++-Standardbibliothek | |
| C-Dokumentation für Source file inclusion
|