Namespaces
Variants

Source file inclusion

From cppreference.net

Bindet eine weitere Quelldatei in die aktuelle Quelldatei in der Zeile unmittelbar nach der Direktive ein.

Inhaltsverzeichnis

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 C23)
__has_include ( string-literal )
__has_include ( < h-pp-tokens > )
(5) (seit C23)
1) Sucht nach einem Header, der eindeutig durch h-char-sequence identifiziert wird, und ersetzt die Direktive durch den gesamten Inhalt des Headers.
2) Sucht nach einer Quelldatei, die durch q-char-sequence identifiziert wird, und ersetzt die Direktive durch den gesamten Inhalt der Quelldatei. Es kann auf (1) zurückgreifen und q-char-sequence als Header-Identifikator behandeln.
3) Wenn weder (1) noch (2) zutrifft, werden pp-tokens einer Makroersetzung unterzogen. Die Anweisung wird nach der Ersetzung erneut versucht, mit (1) oder (2) abgeglichen zu werden.
4) Prüft, ob eine Header- oder Quelldatei zur Einbindung verfügbar ist.
5) Wenn (4) nicht übereinstimmt, werden h-pp-tokens einer Makroersetzung unterzogen. Die Anweisung nach der Ersetzung wird erneut versucht, mit (4) abgeglichen zu werden.
new-line - Das Zeilenumbruchzeichen
h-char-sequence - Eine Sequenz von einem oder mehreren h-char s, wobei das Auftreten eines der folgenden Zeichen zu undefiniertem Verhalten führt:
  • das Zeichen '
  • das Zeichen "
  • das Zeichen \
  • die Zeichensequenz //
  • die Zeichensequenz /*
h-char - Jedes Mitglied des Quellzeichensatzes außer Zeilenumbruch und >
q-char-sequence - Eine Sequenz von einem oder mehreren q-char s, wobei das Auftreten eines der folgenden Zeichen zu undefiniertem Verhalten führt:
  • das Zeichen '
  • das Zeichen \
  • die Zeichensequenz //
  • die Zeichensequenz /*
q-char - Jedes Mitglied des Quellzeichensatzes 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 >

Erklärung

1) Sucht nach der Datei, die durch h-char-sequence identifiziert wird, auf implementationsdefinierte Weise. Die Absicht dieser Syntax ist, nach Dateien unter der Kontrolle der Implementation zu suchen. Typische Implementationen durchsuchen nur Standard-Include-Verzeichnisse. Die Standard-C-Bibliothek ist implizit in diesen Standard-Include-Verzeichnissen enthalten. Die Standard-Include-Verzeichnisse können normalerweise durch den Benutzer über Compiler-Optionen gesteuert werden.
2) Sucht nach der Datei, die durch q-char-sequence identifiziert wird, auf implementationsdefinierte Weise. Die Absicht dieser Syntax ist, nach Dateien zu suchen, die nicht durch die Implementation kontrolliert werden. Typische Implementationen durchsuchen zuerst das Verzeichnis, in dem die aktuelle Datei sich befindet, und nur wenn die Datei nicht gefunden wird, durchsuchen sie die Standard-Include-Verzeichnisse wie bei (1) .
3) Die Präprozessierungs-Tokens nach include in der Direktive werden genauso wie in normalem Text verarbeitet (d.h., jeder als Makroname definierte Bezeichner wird durch seine Ersetzungsliste von Präprozessierungs-Tokens ersetzt). Die nach allen Ersetzungen resultierende Direktive muss einer der beiden vorherigen Formen entsprechen. Die Methode, durch die eine Sequenz von Präprozessierungs-Tokens zwischen < und > Präprozessierungs-Token-Paaren oder einem Paar von " Zeichen zu einem einzelnen Header-Namen-Präprozessierungs-Token kombiniert wird, ist implementierungsdefiniert.
4) Die Header- oder Quelldatei, die durch h-char-sequence oder q-char-sequence identifiziert wird, wird so durchsucht, als ob diese Präprozessor-Token-Sequenz die pp-tokens in Syntax (3) wäre, mit der Ausnahme, dass keine weitere Makroexpansion durchgeführt wird. Wenn eine solche Direktive die syntaktischen Anforderungen einer #include -Direktive nicht erfüllen würde, ist das Programm fehlerhaft. Der __has_include -Ausdruck ergibt 1 , wenn die Suche nach der Quelldatei erfolgreich ist, und 0 , wenn die Suche fehlschlägt.
5) Diese Form wird nur berücksichtigt, falls die Syntax (4) nicht zutrifft, in welchem Fall die Präprozessor-Tokens genau wie in normalem Text verarbeitet werden.

Falls die Datei nicht gefunden wird, ist das Programm fehlerhaft.

__has_include kann in den Ausdrücken von #if und #elif expandiert werden. Es wird von #ifdef , #ifndef , #elifdef , #elifndef und defined als definiertes Makro behandelt, kann aber nirgendwo anders verwendet werden.

(seit C23)

Hinweise

Typische Implementierungen durchsuchen nur Standard-Includeverzeichnisse für Syntax (1). Die Standard-C-Bibliothek ist implizit in diesen Standard-Includeverzeichnissen enthalten. Die Standard-Includeverzeichnisse können normalerweise durch den Benutzer über Compiler-Optionen gesteuert werden.

Die Absicht der Syntax (2) ist es, nach Dateien zu suchen, die nicht durch die Implementierung gesteuert werden. Typische Implementierungen durchsuchen zuerst das Verzeichnis, in dem die aktuelle Datei sich befindet, und greifen dann auf (1) zurück.

Wenn eine Datei eingebunden wird, durchläuft sie die Übersetzungsphasen 1-4, was rekursiv die Expansion verschachtelter #include -Direktiven einschließen kann, bis zu einem implementierungsdefinierten Verschachtelungslimit. Um wiederholtes Einbinden derselben Datei und Endlosrekursion zu vermeiden, wenn eine Datei sich selbst (möglicherweise transitiv) einbindet, werden üblicherweise Header Guards verwendet: Der gesamte Header wird eingewickelt in

#ifndef FOO_H_INCLUDED /* any name uniquely mapped to file name */
#define FOO_H_INCLUDED
// Inhalt der Datei befindet sich hier
#endif

Viele Compiler implementieren auch das nicht-standardisierte pragma #pragma once mit ähnlichen Effekten: Es deaktiviert die Verarbeitung einer Datei, falls dieselbe Datei (wobei die Dateiidentität auf betriebssystemspezifische Weise bestimmt wird) bereits eingebunden wurde.

Ein __has_include -Ergebnis von 1 bedeutet lediglich, dass eine Header- oder Quelldatei mit dem angegebenen Namen existiert. Es bedeutet nicht, dass die Header- oder Quelldatei beim Einbinden keinen Fehler verursachen würde oder etwas Nützliches enthalten würde.

Beispiel

Referenzen

  • C23-Standard (ISO/IEC 9899:2024):
  • 6.4.7 Header-Namen (S: 69)
  • 6.10.1 Bedingte Einbindung (S: 165-169)
  • 6.10.2 Quelltextdatei-Einbindung (S: 169-170)
  • C17-Standard (ISO/IEC 9899:2018):
  • 6.10.2 Source file inclusion (S: 119-120)
  • C11-Standard (ISO/IEC 9899:2011):
  • 6.10.2 Source file inclusion (S: 164-166)
  • C99-Standard (ISO/IEC 9899:1999):
  • 6.10.2 Einbindung von Quelldateien (S: 149-151)
  • C89/C90 Standard (ISO/IEC 9899:1990):
  • 3.8.2 Quelltextdatei-Einbindung

Siehe auch

Eine Liste von C-Standardbibliothek-Header-Dateien
C++-Dokumentation für Quelltextdatei-Einbindung