Namespaces
Variants

Phases of translation

From cppreference.net

Die C-Quelldatei wird vom Compiler verarbeitet, als ob die folgenden Phasen in exakt dieser Reihenfolge ablaufen würden. Die tatsächliche Implementierung kann diese Aktionen kombinieren oder anders verarbeiten, solange das Verhalten dasselbe bleibt.

Inhaltsverzeichnis

Phase 1

1) Die einzelnen Bytes der Quellcodedatei (die im Allgemeinen eine Textdatei in einer Multibyte-Kodierung wie UTF-8 ist) werden auf implementationsdefinierte Weise den Zeichen des source character set zugeordnet. Insbesondere werden betriebssystemabhängige Zeilenendezeichen durch Newline-Zeichen ersetzt.
Das source character set ist ein Multibyte-Zeichensatz, der das basic source character set als Einzelbyte-Teilmenge enthält, bestehend aus den folgenden 96 Zeichen:
a) 5 Leerzeichen (Leerzeichen, horizontaler Tabulator, vertikaler Tabulator, Seitenvorschub, Zeilenumbruch)
b) 10 Ziffernzeichen von '0' bis '9'
c) 52 Buchstaben von 'a' bis 'z' und von 'A' bis 'Z'
d) 29 Satzzeichen: _ { } [ ] # ( ) < > % : ; . ? * + - / ^ & | ~ ! = , \ " '
2) Trigraph-Sequenzen werden durch entsprechende Einzelzeichen-Darstellungen ersetzt. (bis C23)

Phase 2

1) Immer wenn ein Backslash am Ende einer Zeile erscheint (unmittelbar gefolgt vom Newline-Zeichen), werden sowohl Backslash als auch Newline gelöscht, wodurch zwei physische Quellzeilen zu einer logischen Quellzeile kombiniert werden. Dies ist ein Einzel-Durchgang-Operation: Eine Zeile, die mit zwei Backslashes endet, gefolgt von einer leeren Zeile, kombiniert nicht drei Zeilen zu einer.
#include <stdio.h>
#define PUTS p\
u\
t\
s
/* Line splicing is in phase 2 while macros
 * are tokenized in phase 3 and expanded in phase 4,
 * so the above is equivalent to #define PUTS puts
 */
int main(void)
{
 /* Use line splicing to call puts */ PUT\
S\
("Output ends here\\
0Not printed" /* After line splicing, the remaining backslash
               * escapes the 0, ending the string early.
               */
);
}
2) Wenn eine nicht-leere Quelldatei nach diesem Schritt nicht mit einem Newline-Zeichen endet (unabhängig davon, ob sie ursprünglich kein Newline-Zeichen hatte oder mit einem Backslash endete), ist das Verhalten undefiniert.

Phase 3

1) Die Quelldatei wird zerlegt in Kommentare , Folgen von Leerzeichen (Leerzeichen, horizontaler Tabulator, Zeilenumbruch, vertikaler Tabulator und Seitenvorschub) und Präprozessor-Tokens , welche folgende sind
a) Header-Namen: < stdio. h > oder "myfile.h"
c) Präprozessorzahlen, die sowohl Integerkonstanten als auch Fließkommakonstanten umfassen, aber auch einige ungültige Tokens wie 1 .. E + 3. foo oder 0JBK
e) Operatoren und Interpunktionszeichen, wie + , <<= , < % , oder ## .
f) einzelne Nicht-Leerzeichen-Zeichen, die in keine andere Kategorie passen
2) Jeder Kommentar wird durch ein Leerzeichen ersetzt
3) Zeilenumbrüche werden beibehalten, und es ist implementierungsdefiniert, ob Leerzeichenfolgen ohne Zeilenumbruch zu einzelnen Leerzeichen zusammengefasst werden dürfen.

Wenn die Eingabe bis zu einem bestimmten Zeichen in Präprozessor-Token zerlegt wurde, wird das nächste Präprozessor-Token im Allgemeinen als die längste Zeichenfolge genommen, die ein Präprozessor-Token bilden könnte, selbst wenn dies dazu führt, dass die nachfolgende Analyse fehlschlägt. Dies ist allgemein bekannt als maximal munch .

int foo = 1;
// int bar = 0xE+foo; // Fehler: ungültige Präprozessor-Zahl 0xE+foo
int bar = 0xE/*Kommentar wird zu einem Leerzeichen expandiert*/+foo; // OK: 0xE + foo
int baz = 0xE + foo; // OK: 0xE + foo
int pub = bar+++baz; // OK: bar++ + baz
int ham = bar++-++baz; // OK: bar++ - ++baz
// int qux = bar+++++baz; // Fehler: bar++ ++ +baz, nicht bar++ + ++baz
int qux = bar+++/*Rettender Kommentar*/++baz; // OK: bar++ + ++baz

Die einzige Ausnahme von der Maximal-Munch-Regel ist:

#define MACRO_1 1
#define MACRO_2 2
#define MACRO_3 3
#define MACRO_EXPR (MACRO_1 <MACRO_2> MACRO_3) // OK: <MACRO_2> ist kein Header-Name

Phase 4

1) Preprocessor wird ausgeführt.
2) Jede Datei, die mit der #include -Direktive eingebunden wird, durchläuft rekursiv die Phasen 1 bis 4.
3) Am Ende dieser Phase werden alle Präprozessor-Direktiven aus der Quelle entfernt.

Phase 5

1) Alle Zeichen und Escape-Sequenzen in Zeichenkonstanten und Zeichenkettenliteralen werden vom Quellzeichensatz in den Ausführungszeichensatz konvertiert (der ein Multibyte-Zeichensatz wie UTF-8 sein kann, solange alle 96 Zeichen des grundlegenden Quellzeichensatzes aus Phase 1 Einzelbyte-Repräsentationen besitzen). Wenn das durch eine Escape-Sequenz spezifizierte Zeichen kein Mitglied des Ausführungszeichensatzes ist, ist das Ergebnis implementierungsdefiniert, jedoch garantiert kein Null-(Breit-)Zeichen.

Hinweis: Die bei dieser Stufe durchgeführte Konvertierung kann in einigen Implementierungen durch Kommandozeilenoptionen gesteuert werden: gcc und clang verwenden - finput - charset zur Angabe der Kodierung des Quellzeichensatzes, - fexec - charset und - fwide - exec - charset zur Angabe der Kodierungen des Ausführungszeichensatzes in den Zeichenkettenliteralen und Zeichenkonstanten ohne Kodierungspräfix (seit C11) .

Phase 6

Benachbarte String-Literale werden verkettet.

Phase 7

Die Kompilation findet statt: Die Tokens werden syntaktisch und semantisch analysiert und als Übersetzungseinheit übersetzt.

Phase 8

Das Linking findet statt: Übersetzungseinheiten und Bibliothekskomponenten, die benötigt werden, um externe Referenzen zu erfüllen, werden in ein Programmabbild zusammengeführt, das die für die Ausführung in seiner Ausführungsumgebung (dem Betriebssystem) benötigten Informationen enthält.

Referenzen

  • C23-Standard (ISO/IEC 9899:2024):
  • 5.1.1.2 Übersetzungsphasen (S: TBD)
  • 5.2.1 Zeichensätze (S: TBD)
  • 6.4 Lexikalische Elemente (S: TBD)
  • C17-Standard (ISO/IEC 9899:2018):
  • 5.1.1.2 Übersetzungsphasen (S: 9-10)
  • 5.2.1 Zeichensätze (S: 17)
  • 6.4 Lexikalische Elemente (S: 41-54)
  • C11-Standard (ISO/IEC 9899:2011):
  • 5.1.1.2 Übersetzungsphasen (S: 10-11)
  • 5.2.1 Zeichensätze (S: 22-24)
  • 6.4 Lexikalische Elemente (S: 57-75)
  • C99-Standard (ISO/IEC 9899:1999):
  • 5.1.1.2 Übersetzungsphasen (S: 9-10)
  • 5.2.1 Zeichensätze (S: 17-19)
  • 6.4 Lexikalische Elemente (S: 49-66)
  • C89/C90 Standard (ISO/IEC 9899:1990):
  • 2.1.1.2 Übersetzungsphasen
  • 2.2.1 Zeichensätze
  • 3.1 Lexikalische Elemente

Siehe auch

C++ Dokumentation für Phasen der Übersetzung