2012-01-12 3 views
20

Являются ли этапы компиляции программы на С ++, указанной стандартом?Каковы этапы компиляции программы на C++?

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

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

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

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

+3

Вот [страница руководства использует GCC Internals в] (http://gcc.gnu.org/onlinedocs/gccint/Passes.html#Passes) , Я думал, что он использовал язык, который вы хотели, но, очевидно, нет. Если вы посмотрите в источнике GCC, то есть множество отдельных проходов оптимизации. Я бы предположил, что нет, стандарт указывает, что нужно для достижения не того, как он должен это делать, и что лучшим выбором будет учебный курс или учебник по составлению компилятора - я уверен, что вокруг много. – Rup

+0

@sharptooth Я отбросил вопрос - я считаю, что этот титул может быть гораздо легче найти людьми, ищущими то же самое. –

+0

@ Luchian Grigore: Хорошо, я просто, хотя изменение названия действительно имело значение - «как это обычно делается» v «что Стандарт говорит о том, как это должно быть сделано». В любом случае, это ваш вопрос, вы решаете. – sharptooth

ответ

33

Являются ли этапы компиляции программы на С ++, указанной стандартом?

Да и нет.

Стандарт C++ определяет 9 "фаз перевода". Цитируя the N3242 draft (10MB 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). Результирующие маркеры синтаксически и семантически анализируются, а переведен как единица перевода. [СНиП]
  8. Переведенные единицы перевода и конкретизация единицы объединены следующим образом: [СНиП]
  9. Все внешние ссылки на объекты будут решены. Компоненты библиотеки связаны для удовлетворения внешних ссылок на объекты, не определенные в текущем переводе . Все такие выходные данные переводчика собираются в образ программы , который содержит информацию, необходимую для выполнения в ее среде исполнения .

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

Как указано [СНИП] маркеры, я не цитировал весь раздел, достаточно просто, чтобы получить представление в поперечнике.

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

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

(фазы перевода C являются аналогичными, но # 8 опускается.)

+0

FWIW, в gcc-фазе 6 не является частью предварительной обработки ('gcc -E' не объединяет смежные строковые литералы). У меня нет другого компилятора для сравнения. –

+1

В сноске на этой странице говорится: «Реализации должны вести себя так, как если бы эти отдельные фазы происходили, хотя на практике разные фазы могли складываться вместе». – rodrigo

+0

@rodrigo: Я уже цитировал эту сноску. Вероятно, вы пропустили это, потому что я не поставил его внизу цитаты. Я только что переехал туда. –

6

9 так называемых «фаз перевода» указаны в стандарте в [lex.phases] (2.2 в C++ 11, 2.1 на C++ 03).

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

Ссылка, с другой стороны, оставлена ​​главным образом для реализации, чтобы решить, как она на самом деле достигнута, потому что стандарту все равно , как данное имя просматривается, как раз то, на что оно ссылается.

Он не дает никаких подробностей о разборе, либо он просто говорит: «Полученные жетоны синтаксически и семантически анализируются и переводятся». Это потому, что все главы 3-15 необходимы для заполнения этой детали.

Он не упоминает внутренние представления во время разбора/перевода вообще, и он также не упоминает фазы оптимизации - они важны для дизайна компиляторов, но они не важны для стандарта. Оптимизация может происходить в разных местах в разных компиляторах. В течение долгого времени оптимизация была почти полностью на этапе компиляции, перед выпуском объектных файлов, а линкеры были немыми в качестве сообщения. Я думаю, что теперь серьезные реализации C++ могут сделать хотя бы некоторую оптимизацию в нескольких TU. Таким образом, «другие» не просто исключены из стандарта, они действительно меняются со временем.

3

Спецификация C++ преднамеренно расплывчата во многих отношениях, главным образом, чтобы оставаться независимой от реализации. Многие области, где язык является неопределенным, больше не представляют большой проблемы - например, вы обычно можете полагаться на символ, состоящий из 8 бит. Тем не менее, другие проблемы, такие как компоновка структур, которые используют множественное наследование, представляют собой реальную проблему, равно как и последствия виртуальных функций для классов. Эти проблемы влияют на совместимость кода, сгенерированного с помощью разных компиляторов. Бинарный интерфейс приложения (или ABI) C++ не строго определен, и в результате вам приходится иногда погружаться в C, где это становится проблематичным. Хорошим примером является написание плагина.

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

У меня был краткий взгляд, довольно сложно найти описания отдельных компиляторов. Я сомневаюсь, что там много коммерческих компиляторов, таких как предложение Microsoft, исключительно по коммерческим соображениям. GCC - ваш лучший выбор, although Microsoft is happy to describe the process. Это довольно банальный материал: компиляторы все работают практически так же. Реальное золото заключается в том, как они выполняют эти этапы, алгоритмы и структуры данных, которые они используют. В этом отношении I recommend this book. Несколько лет назад я купил совершенно новый экземпляр для университетского курса, и я заимствовал большинство моих учебников из библиотеки :).

Смежные вопросы