Namensräume
Varianten
Aktionen

Einbeziehung von Quelldateien

Von cppreference.com

Fügt eine andere Quelldatei an der Zeile unmittelbar nach der Direktive in die aktuelle Quelldatei 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 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. Sie kann auf (1) zurückfallen und q-char-sequence als Header-Identifikator behandeln.
3) Wenn weder (1) noch (2) zutreffen, wird pp-tokens einer Makroersetzung unterzogen. Die Direktive nach der Ersetzung wird erneut versucht, mit (1) oder (2) abzugleichen.
4) Prüft, ob ein Header oder eine Quelldatei zur Einbeziehung verfügbar ist.
5) Wenn (4) nicht zutrifft, wird h-pp-tokens einer Makroersetzung unterzogen. Die Direktive nach der Ersetzung wird erneut versucht, mit (4) abzugleichen.
new-line - Das Zeilenumbruchzeichen
h-char-sequence - Eine Sequenz aus einem oder mehreren h-chars, wobei das Auftreten eines der folgenden undefiniertes Verhalten verursacht
  • 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 aus einem oder mehreren q-chars, wobei das Auftreten eines der folgenden undefiniertes Verhalten verursacht
  • das Zeichen '
  • das Zeichen \
  • die Zeichensequenz //
  • die Zeichensequenz /*
q-char - Jedes Mitglied des Quellzeichensatzes außer Zeilenumbruch und "
pp-tokens - Eine Sequenz aus einem oder mehreren Präprozessor-Tokens
string-literal - Ein String-Literal
h-pp-tokens - Eine Sequenz aus einem oder mehreren Präprozessor-Tokens außer >

[bearbeiten] Erklärung

1) Sucht die durch h-char-sequence identifizierte Datei auf eine implementierungsdefinierte Weise. Die Absicht dieser Syntax ist es, nach Dateien zu suchen, die unter der Kontrolle der Implementierung stehen. Typische Implementierungen suchen nur in Standard-Include-Verzeichnissen. 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 die durch q-char-sequence identifizierte Datei auf eine implementierungsdefinierte Weise. Die Absicht dieser Syntax ist es, nach Dateien zu suchen, die nicht von der Implementierung gesteuert werden. Typische Implementierungen durchsuchen zuerst das Verzeichnis, in dem sich die aktuelle Datei befindet, und suchen nur, wenn die Datei nicht gefunden wird, in den Standard-Include-Verzeichnissen wie bei (1).
3) Die Präprozessor-Tokens nach include in der Direktive werden wie in normalem Text verarbeitet (d. h., jeder Bezeichner, der derzeit als Makroname definiert ist, wird durch seine Ersetzungsliste von Präprozessor-Tokens ersetzt). Die Direktive, die nach allen Ersetzungen resultiert, muss eine der beiden vorherigen Formen entsprechen. Die Methode, mit der eine Sequenz von Präprozessor-Tokens zwischen einem Präprozessor-Token-Paar < und > oder einem Paar von "-Zeichen zu einem einzigen Header-Namen-Präprozessor-Token kombiniert wird, ist implementierungsdefiniert.
4) Die durch h-char-sequence oder q-char-sequence identifizierte Header- oder Quelldatei wird durchsucht, als ob diese Präprozessor-Token-Sequenz die pp-tokens in Syntax (3) wären, mit der Ausnahme, dass keine weitere Makroerweiterung durchgeführt wird. Wenn eine solche Direktive nicht den syntaktischen Anforderungen einer #include-Direktive entspricht, ist das Programm schlecht geformt. Der Ausdruck __has_include ergibt 1, wenn die Suche nach der Quelldatei erfolgreich ist, und 0, wenn die Suche fehlschlägt.
5) Diese Form wird nur berücksichtigt, wenn Syntax (4) nicht zutrifft. In diesem Fall werden die Präprozessor-Tokens wie in normalem Text verarbeitet.

Wenn die Datei nicht gefunden wird, ist das Programm schlecht geformt.

__has_include kann im Ausdruck von #if und #elif erweitert werden. Es wird von #ifdef, #ifndef, #elifdef, #elifndef und defined als definiertes Makro behandelt, kann aber nirgendwo anders verwendet werden.

(seit C23)

[bearbeiten] Hinweise

Typische Implementierungen durchsuchen für Syntax (1) 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.

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

Wenn eine Datei eingeschlossen wird, wird sie durch die Übersetzungsphasen 1-4 verarbeitet, was, rekursiv, die Erweiterung von verschachtelten #include-Direktiven bis zu einer implementierungsdefinierten Verschachtelungsgrenze umfassen kann. Um die wiederholte Einbeziehung derselben Datei und endlose Rekursionen zu vermeiden, wenn eine Datei sich selbst, vielleicht transitiv, einschließt, werden *Header-Schutzvorrichtungen* häufig verwendet: Der gesamte Header wird 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 die nicht standardmäßige pragma #pragma once mit ähnlichen Effekten: Sie deaktiviert die Verarbeitung einer Datei, wenn dieselbe Datei (wobei die Identität der Datei betriebssystemspezifisch bestimmt wird) bereits eingeschlossen wurde.

Ein Ergebnis von 1 von __has_include bedeutet nur, dass eine Header- oder Quelldatei mit dem angegebenen Namen existiert. Es bedeutet nicht, dass die Header- oder Quelldatei, wenn sie eingeschlossen wird, keinen Fehler verursacht oder etwas Nützliches enthält.

[bearbeiten] Beispiel

[bearbeiten] Referenzen

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

[bearbeiten] Siehe auch

Eine Liste von C-Standardbibliotheks-Header-Dateien
C++-Dokumentation für Einbeziehung von Quelldateien