2012-01-31 3 views
23

Я читал о предложении модулей на C++ (latest draft), но я не совсем понимаю, какие проблемы (задачи) он должен решить.Модули C++ и C++ ABI

Является ли его целью предоставить модуль, построенный одним компилятором для использования любым другим компилятором (на той же ОС/архитектуре, конечно)? То есть, составляет ли предложение стандартизацию C++ ABI?

Если нет, есть ли еще какое-то предложение, которое будет стандартизировать C++ ABI и позволить компиляторам взаимодействовать?

ответ

31

Предварительно скомпилированные заголовки (PCH) представляют собой специальные файлы, которые могут быть созданы некоторыми компиляторами для файла .cpp. То, что они есть, это именно то, что: предварительно скомпилированный исходный код. Это исходный код, который был передан через компилятор и встроен в формат, зависящий от компилятора.

PCHs обычно используются для ускорения компиляции. Вы помещаете обычно используемые заголовки в PCH, а затем просто включаете PCH. Когда вы делаете #include на PCH, ваш компилятор фактически не выполняет обычную работу #include. Вместо этого они загружают эти предварительно скомпилированные символы непосредственно в компилятор. Не работает препроцессор C++. Отсутствует компилятор C++. Нет #, включая миллион разных файлов. Загружается один файл, а символы отображаются полностью в рабочей области вашего компилятора.

Я упоминаю все это, потому что модули являются PCHs в их совершенной форме. PCH - это, в основном, гигантский взлом, построенный поверх системы, которая не позволяет использовать реальные модули. Назначение модулей в конечном итоге - возможность взять файл, сгенерировать файл модуля, специфичный для компилятора, который содержит символы, а затем другой файл загружает этот модуль по мере необходимости. Символы предварительно скомпилированы, поэтому снова не нужно # включать кучу материала, запускать компилятор и т. Д. В вашем коде говорится: import thing.foo, и он появляется.

Посмотрите на любой из стандартных библиотек библиотеки STL. Например, возьмите <map>. Коэффициенты хороши, что этот файл является либо гигантским, либо имеет много #include других файлов, которые делают полученный файл гигантским. Это очень много синтаксического анализа C++, который должен произойти. Это должно произойти для каждый .cpp-файл, который содержит #include <map>. Каждый раз, когда вы компилируете исходный файл, компилятор должен перекомпилировать то же самое. Над. И более. И снова.

<map> изменить между сборниками? Нет, но ваш компилятор не может этого знать. Поэтому он должен продолжать перекомпилировать его.Каждый раз, когда вы касаетесь файла .cpp, он должен скомпилировать каждый заголовок, который включает этот .cpp-файл. Даже если вы не касались этих заголовков или исходных файлов, которые затрагивают эти заголовки.

Файлы PCH были способом обойти эту проблему. Но они ограничены, потому что они просто хак. Вы можете включить только один файл на .cpp, потому что это должно быть первое, что включено в .cpp-файлы. И поскольку есть только один PCH, если вы делаете что-то, что изменяет PCH (например, добавляет ему новый заголовок), вы должны перекомпилировать все в этом PCH.

Модули практически не имеют никакого отношения к кросс-компилятору ABI (хотя наличие одного из них было бы приятным, а модули могли бы немного упростить его определение). Их основная цель - ускорить время компиляции.

+1

Основная цель заключается не только в ускорении времени компиляции .....: D –

10

Модули - это Java, C# и многие другие современные языки. Они значительно сокращают время компиляции просто потому, что код, который находится в сегодняшнем заголовке, не нужно разбирать снова и снова, каждый раз, когда он включен. Когда вы скажете #include <vector>, содержимое <vector> будет скопировано в текущий файл. #include На самом деле это не что иное, как копирование и вставка.

В мире модулей вы просто говорите, например, import std.vector;, и компилятор загружает таблицу запроса/символа этого модуля. Файл модуля имеет формат, позволяющий компилятору разбирать и использовать его. Он также обрабатывается только , когда модуль скомпилирован. После этого созданный компилятором файл модуля запрашивается только для необходимой информации.

Поскольку модуль файлы сгенерированный компилятором, они будут очень тесно связаны с внутренним представлением компилятора кода C++ (AST) и как таковой, скорее всего, не будет портативным (так же, как сегодняшние .o/.so/.a файлов , из-за имени mangling и т.п.).

7

Модули на C++ должны быть в первую очередь лучше, чем сегодняшние решения, то есть когда библиотека состоит из файла * .so и * .h с API. Они должны решать проблемы, которые сегодня с директивами #includes, то есть:

  • требует macroguards (макросов, которые мешают, что определения приводятся несколько раз)
  • строго на основе текст (так что они могут быть обмануты и в нормальных условиях они переинтерпретируются, что также дает возможность выглядеть по-разному в разных единицах компиляции, чтобы быть связанными друг с другом).
  • не различают зависимые библиотеки, которые используются только инструментально и производятся (особенно если заголовок предоставляет встроенную функцию шаблоны)

Несмотря на то, что говорит Xeo, модули не существуют на Java или C#. Фактически, на этих языках «загрузка модулей» опирается на «хорошо», здесь у вас есть CLASSPATH и поиск через него, чтобы найти любые модули, которые могут предоставлять символы, которые фактически использует исходный файл ». Объявление «import» в Java вообще не является «запросом модуля» - так же, как «использование» в C++ («import ns.ns2. *» В Java такое же, как «использование пространства имен ns :: ns2» в C++) , Я не думаю, что такое решение можно использовать в C++. Самое близкое приближение, которое я могу себе представить, это пакеты в Vala или модули в Tcl (версии 8.5).

Я полагаю, что C++-модули не могут быть кросс-платформенными или динамически загруженными (для них требуется специальный загрузчик динамического модуля C++ - это не невозможно, но сегодня трудно определить). Они определенно зависят от платформы и также должны быть настроены по запросу. Но стабильный C++ ABI практически необходим только в пределах одной системы, как и сейчас с C++ ABI.

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