Пространства имён
Варианты
Действия

Фазы транслятора

Материал из cppreference.com
< cpp‎ | language

Исходный файл C++ должен быть препроцессирован компилятором так, как будто последовательно выполняются следующие фазы:

Содержание

[править] Фаза 1

1) Отдельные байты файла исходного кода сопоставляются (в порядке реализации) символам основного набора символов источника. В частности, зависящие от ОС индикаторы конца строки заменяются символами новой строки. Основной набор символов-источников состоит из 96 символов:
a) 5 пробельных символов (пробел, горизантальная и вертикальная табуляции, новая строка и конец файла)
b) 10 цифр от '0' до '9'
c) 52 символа в нижнем (от 'a' до 'z') и верхнем регистре (от 'A' до 'Z' )
d) 29 знака пунктуации: _ { } [ ] # ( ) < > % : ; . ? * + - / ^ & | ~ ! = , \ " '
2) Любой символ, который не может быть сопоставлен символу из базового набора заменяется на его универсальное имя (с управляющим символом \u или \U) или на какую-либо зависимую от реализации форму.
3) Триграфы заменяются соответствующими односимвольными представлениями.
(до C++17)

[править] Фаза 2

1 ) Всякий раз, когда обратная косая черта появляется в конце строки (сразу же после символа новой строки), как обратная косая черта, так и новая строка удаляются, объединяя две физические строки источника в одну логическую строку источника. Это однопроходная операция; Строка, заканчивающаяся двумя обратными слешами, за которой следует пустая строка, не объединяет три строки в одну. Если на этой фазе сформировано универсальное имя символа (\ uXXX), поведение не определено.
2 ) Если непустой исходный файл не заканчивается символом новой строки после этого шага (независимо от того, у него не было новой строки или закончилось обратным слэшем), поведение не определено (до C++11) добавляется символ завершающей новой строки (начиная с C++11).

[править] Фаза 3

1 ) Исходный файл разбивается на комментарии, последовательности пробельных символов (пробел, горизонтальная вкладка, новая строка, вертикальная вкладка и форма-фид) и «токены предварительной обработки», Которые являются следующими:
a) заголовков, такие как <iostream> или "myfile.h" (распознаются только после #include)
c) номера предварительной обработки
e) операторы и пунктуаторы (в том числе альтернативные tokens), такие как +, <<=,new,Шаблон:C,## или и
f) отдельные непробельные символы, которые не подходят ни к одной другой категории
2 ) Любые преобразования, выполненные во время фаз 1 и 2 между начальной и заключительной двойной кавычкой любой строки, возвращаются.
(начиная с C++11)
3 ) Каждый комментарий заменяется одним пробелом.

Новые строки сохраняются, и не указано, могут ли последовательности символов пробела не-новой строки быть свернуты в одиночные пробелы.

[править] Фаза 4

1 ) Выполняется препроцессор.
2 ) Каждый файл, введенный с помощью директивы #include, рекурсивно проходит фазы 1-4.
3 ) В конце этой фазы все директивы препроцессора удаляются из источника.

[править] Фаза 5

1 ) Все символы из списка литералов и строковые литералы преобразуются из исходного набора символов в «набор символов выполнения» (который может быть многобайтным символом Такой как UTF-8, если 96 символов «основного набора символов источника», перечисленных в фазе 1, имеют однобайтовые представления).
2 ) Управляющие последовательности и универсальные имена символов в символьных литералах и неровные строковые литералы расширяются и преобразуются в «набор символов выполнения». Если символ, указанный универсальным символьным именем, не является членом набора символов выполнения, результат определяется реализацией, но гарантированно не является нулевым (широким) символом.

Примечание: преобразование, выполняемое на этом этапе, может управляться параметрами командной строки в некоторых реализациях: gcc и clang используют -finput-charset для указания кодировки исходного набора символов -fwide-exec-charset и -fwide-exec-charset, чтобы указать кодировки исполняемого символьного набора в строковых и символьных литералах , которые не имеют префикс, подходящий для декодирования (начиная с C++11).

[править] Фаза 6

Смежные строковые литералы объединяются.

[править] Фаза 7

Выполняется компиляция: каждый токен предварительной обработки преобразуется в токен. Эти токены анализируются синтаксически и семантически и переводятся как единицы перевода.

[править] Фаза 8

Каждая единица трансляции проверяется, чтобы создать список необходимых шаблонных экземпляров, включая те, которые запрашиваются в явные реализации. Определения шаблонов расположены, и требуемые экземпляры выполняются для создания «единиц конкретизации».

[править] Фаза 9

Единицы трансляции, единицы экземпляра и компоненты библиотек, необходимые для удовлетворения внешних ссылок, собираются в образ программы, который содержит информацию, необходимую для выполнения в ее среде выполнения.

[править] Примечания

Некоторые компиляторы не реализуют единицы экземпляра (также известные как репозитории шаблонов или Шаблонные регистры) и просто скомпилировать каждый экземпляр шаблона на этапе 7, сохраняя код в Объектный файл, где он неявно или явно запрашивается, а затем компоновщик сворачивает эти скомпилированные экземпляры в один на этапе 9.


[править] References

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

[править] See also

Справка по Cphases of translation