Przestrzenie nazw
Warianty
Działania

Fazy translacji

Z cppreference.com
< cpp‎ | language

Plik źródłowy C++ jest przetwarzany przez kompilator, przechodząc przez następujące fazy, w tej kolejności:

Spis treści

[edytuj] Faza 1

1) Indywidualne bajty kodu źródłowego zostają sprowadzone (w sposób zależny od implementacji) do znaków zawierających się w bazowym zestawie znaków kodu źródłowego(ang). W szczególności znaki końca linii, które są zależne od systemu operacyjnego, są zastąpione znakami nowej linii. Bazowy zestaw znaków kodu źródłowego składa się z 96 znaków:
a) 5 białych znaków (spacja, pozioma tabulacja, pionowa tabulacja, form feed, nowa linia)
b) 10 znaków cyfr od '0' do '9'
c) 52 liter od 'a' do 'z' oraz od 'A' do 'Z'
d) 29 znaków interpunkcyjnych: _ { } [ ] # ( ) < > % : ; . ? * + - / ^ & | ~ ! = , \ " '
2) Każdy znak, który nie może zostać sprowadzony do znaku z bazowego zestawu znaków kodu źródłowego jest zastąpiony jego uniwersalną nazwą znaku(ang) (poprzedzone znakiem ucieczki \u lub \U) lub jakąś porównywalną formą zależną od implementacji.
3) Sekwencje trigrafów są zastąpione przez odpowiadające im pojedyncze znaki.
(do C++17)

[edytuj] Faza 2

1) Kiedy zostaje napotkany backslash przed końcem linii (bezpośrednio przed znakiem nowej linii), i backslash i znak nowej linii są usuwane, łącząc dwie następujące po sobie fizyczne linie w jedną linię logiczną. Jest to jednorazowa operacja; koniec linii z dwoma backslashami i następującą po niej pustą linią nie łączy 3 linii w jedną. Jeśli uniwersalny znak (\uXXX) zostaje uformowany w tej fazie, zachowanie pozostaje niezdefiniowane.
2) Jeśli niepusty plik źródłowy nie kończy się znakiem nowej linii, po tym kroku (bez względu na to, czy wcześniej miał znak nowej linii, czy kończył się backslashem), zachowanie pozostaje niezdefiniowane (do C++11)znak końca linii zostaje dodany na sam koniec (od C++11).

[edytuj] Faza 3

1) Plik źródłowy zostaje rozłożony do postaci osobnych: komentarzy, sekwencji białych znaków (spacja, pozioma tabulacja, nowa linia, pionowa tabulacja, i form-feed), oraz tokeny preprocesingu, w których skład wchodzą:
a) nazwy plików nagłówkowych, jak np.: <iostream> lub "myfile.h" (rozpoznawane tylko po #include)
c) liczby preprocesora
d) literały znakowe i stringowe , włącznie ze zdefiniowanymi przez użytkownika (od C++11)
e) operatory i znaki interpunkcyjne (włączając alternatywne tokeny), takie jak +, <<=, new, <%, ##, czy and
f) pojedyncze znaki, które nie pasują do żadnej innej kategorii
2) Wszystkie transformacje, które miały miejsce w fazie 1 oraz fazie 2 pomiędzy znakami "" jakiegokolwiek literału raw stringa zostają cofnięte.
(od C++11)
3) Każdy komentarz zostaje zastąpiony pojedynczą spacją.

Nowe linie są zachowane, a to czy sekwencje białych znaków zostaną zamienione pojedynczą spacją nie jest określone.

[edytuj] Faza 4

1) Preprocesor wykonuje swoje działanie.
2) Każdy plik wprowadzony przez dyrektywę #include przechodzi rekursywnie przez fazy 1 do 4.
3) Na końcu tej fazy wszystkie dyrektywy preprocesora zostają usunięte ze źródeł.

[edytuj] Faza 5

1) Wszystkie znaki z literałów znakowych oraz literałów stringowych są konwertowane z zestawu znaków źródeł do zestawu znaków wykonywania(ang) (który może być zestawem, w którym znaki składają się z wielu bajtów, np. UTF-8, dopóki wszystkie 96 znaków bazowego zestawu znaków kodu źródłowego wymienione w fazie 1 mają jedno-bajtową reprezentację).
2) Sekwencje ucieczki oraz uniwersalne nazwy znaków w literałach znakowych oraz literałach nie-surowych stringów zostają rozszerzone i skonwertowane do zestawu znaków wykonywania. Jeśli znak, wcześniej oznaczony przy użyciu uniwersalnej nazwy znaku, nie jest częścią zestawu znaków wykonania, wynik jest zależny od implementacji, ale z gwarancją, że nie będzie pustym znakiem.

Uwaga: konwersja wykonana w tej fazie może być kontrolowana przez linię poleceń w niektórych implementacjach: gcc i clang używają -finput-charset by ustalić kodowanie źródłowego zestawu znaków, -fexec-charset oraz -fwide-exec-charset by ustalić kodowanie zestawu znaków wykonywania w literałach znakowych oraz stringowych które nie mają prefixu enkodowania (od C++11).

[edytuj] Faza 6

Sąsiadujące literały stringów są łączone.

[edytuj] Faza 7

Etap kompilacji: każdy token preprocessingu jest konwertowany na zwykły token. Następnie wszystkie tokeny są analizowane pod względem składni oraz semantyki i tłumaczone w jednostce translacji.

[edytuj] Faza 8

Każda jednostka translacji jest sprawdzana, pod względem listy potrzebnych instancjacji szablonów(ang), wliczając te, wymagane przez jawne instancjacje szablonów(ang). Definicje szablonów zostają wyszukane i następnie potrzebne instancjacje zostają przeprowadzone, by utworzyć jednostki instancjacji(ang).

[edytuj] Faza 9

Jednostki translacji, instacjacji oraz komponenty bibliotek, które są wymagane przez zewnętrzne referencje(ang) zostają zebrane w obraz programu, który zawiera informacje potrzebne do wykonania w jego środowisku wykonania.

[edytuj] Uwagi

Niektóre kompilatory nie implementują jednostek instancjacji (znanych również jako repozytoria szablonów lub rejestry szablonów) i po prostu kompilują każdą instacjację w fazie 7, przetrzymując ich kod w plikach obiektowych, gdzie jest to niejawnie bądź jawnie żądane, a następnie linker łączy skompilowane instancjacje w jedno, w fazie 9.

[edytuj] Odnośniki

  • standard C++11 (ISO/IEC 14882:2011):
  • 2.2 Fazy translacji [lex.phases]
  • standard C++98 (ISO/IEC 14882:1998):
  • 2.1 Fazy translacji [lex.phases]

[edytuj] Zobacz także

C documentation for Fazy translacji