Каковы этапы компиляции программы на C++?

Указаны ли этапы компиляции программы на C++ в стандарте?

Если да, то какие?

Если нет, то ответ для широко используемого компилятора (я бы предпочел MSVS)был бы замечательным.

Я говорю о препроцессинге, токенизации, парсинге и тому подобном. Каков порядок их выполнения и что они делают в частности?

EDIT: Я знаю, что делают компиляция, линковка и препроцессирование, меня в основном интересуют остальные и их порядок. Объяснения по этим вопросам, конечно, также приветствуются, поскольку я могу быть не единственным, кто заинтересован в ответе.

24
задан sbi 25 September 2012 в 08:13
поделиться

1 ответ

Стадии компиляции программы на C ++ определены стандартом?

Да и нет.

Стандарт C ++ определяет 9 «фаз перевода». Ссылаясь на черновик N3242 (10 МБ PDF) от 2011-02-28 (до выпуска официального стандарта C ++ 11), раздел 2.2:

Приоритет среди синтаксических правил перевода определяется следующими этапами [см. сноску] .

  1. Физические символы исходного файла отображаются, в зависимости от реализации, в базовый исходный набор символов (ввод символов новой строки для индикаторов конца строки), если необходимо. [SNIP]
  2. Каждый экземпляр символа обратной косой черты (\), за которым сразу следует символ новой строки, удаляется, объединяя физические исходные строки для формирования логических исходных строк. [SNIP]
  3. Исходный файл разбит на токены предварительной обработки (2.5) и последовательности символов пробела (включая комментарии). [SNIP]
  4. Выполняются директивы предварительной обработки, расширяются вызовы макросов и выполняются выражения унарного оператора _Pragma. [SNIP]
  5. Каждый элемент исходного набора символов в символьном литерале или строковом литерале, а также каждая escape-последовательность и универсальное имя-символа в символьном литерале или не-сырой строковый литерал, преобразуется в соответствующий член набора символов выполнения; [SNIP]
  6. Литеральные токены смежных строк объединяются.
  7. Пробельные символы, разделяющие токены, больше не являются значимыми. Каждый токен предварительной обработки преобразуется в токен. (2.7). Полученные токены синтаксически и семантически анализируются и переводятся как единица перевода. [SNIP]
  8. Переведенные единицы перевода и единицы реализации объединяются следующим образом: [SNIP]
  9. Все внешние ссылки на объекты разрешены. Компоненты библиотеки связаны для удовлетворения внешних ссылок на объекты, не определенные в текущем переводе. Весь такой вывод транслятора собирается в образ программы, который содержит информацию, необходимую для выполнения в среде выполнения.

[сноска] Реализации должны вести себя так, как будто эти отдельные фазы происходят, хотя на практике разные фазы могут складываться вместе.

Как отмечают маркеры [SNIP] , я не процитировал весь раздел, просто достаточно, чтобы изложить идею.

Чтобы подчеркнуть, компиляторы не обязаны следовать этой точной модели, пока конечный результат такой, как если бы они это сделали.

Фазы 1-6 в большей или меньшей степени соответствуют препроцессору, 7 - тому, что вы обычно воспринимаете как компиляцию, 8 имеет дело с шаблонами, а 9 соответствует связыванию.

(фазы перевода С аналогичны, но № 8 опущен.)

38
ответ дан 28 November 2019 в 23:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: