Модули C ++ - почему они были удалены из C ++ 0x? Вернутся ли они позже?

110

Я только что обнаружил этот старый черновик C ++ 0x о модулях в C ++ 0x.

Идея заключалась в том, чтобы выйти из текущей системы .h / .cpp, написав только файлы .cpp, которые затем будут генерировать файлы модулей во время компиляции, которые затем, в свою очередь, будут использоваться другими файлами .cpp.

Похоже, это действительно отличная функция.

Но у меня вопрос: почему они удалили его из C ++ 0x? Было ли это из-за слишком большого количества технических трудностей? Нехватка времени? И как вы думаете, они рассмотрят возможность работы над дополнительной версией C ++?

Tomaka17
источник

Ответы:

70

В публикации State of C ++ Evolution (Post San Francisco 2008) предложение по модулям было отнесено к категории «Заголовок для отдельного TR:»

Эти темы считаются слишком важными, чтобы ждать выхода другого стандарта после C ++ 0x перед публикацией, но слишком экспериментальными, чтобы доработать их вовремя для следующего стандарта. Таким образом, эти функции будут представлены в техническом отчете при первой возможности.

Предложение модулей просто не было готово, и ожидание его отложило бы завершение стандарта C ++ 0x. На самом деле он не был удален, он просто никогда не был включен в рабочий документ.

Джеймс МакНеллис
источник
89

Проект модулей C ++ (Техническая спецификация после C ++ 17)

Проект и несколько обновленных версий спецификации модуля C / C ++ были опубликованы WG21 на open-std.org. Здесь я буду ссылаться только на самые свежие документы:

  • Рабочий проект, расширения C ++ для модулей N4610 (октябрь 2016 г.).
  • Четвертая редакция опубликована как P0142R0 (март 2016 г.).
  • Формулировка для модулей опубликована как P0143R2 (март 2016 г.).
  • Команда clang опубликовала вторую версию своих изменений: P0273R1 (октябрь 2016 г.).

Следующие сообщения в блоге содержат сводку встреч по стандартам и, в частности, сводку текущего статуса проекта модулей:

Обновление: как объясняется в отчете о поездке Кона, на который я ссылался выше, в настоящее время есть два конкурирующих предложения, одно от Microsoft и одно от Clang. Предлагаемое решение от Microsoft не позволяет экспортировать макросы, в то время как решение от команды Clang будет поддерживать экспорт макросов. Пока только Microsoft официально представила черновик спецификации модуля.

Спецификация модуля, предложенная Microsoft

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

moduleКлючевое слово , чтобы объявить модуль, несколько файлов могут объявить это построить один модуль (но для каждого модуля только один сборник-блок может содержать export {}раздел):

module M;

importКлючевое слово для импорта модулей, вместо importнего может быть также принято решение использовать using moduleвместо этого, поэтому новый импорт ключевых слов можно было бы избежать.

import std.io;
import module.submodule;

exportСинтаксис, который определяет публичные заявления , которые являются частью этого модуля, не интерфейс деклараций , которые не должны быть экспортированы как часть модуля будет определяться вне экспортного блока. Объявления могут быть любым видом объявления в C / C ++, то есть не только функциями, но также переменными, структурами, шаблонами, пространствами имен и классами:

export {
    int f(int);
    double g(double, int);

    int foo;

    namespace Calc {
         int add(int a, int b);
    }        
}

void not_exported_function(char* foo);

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

#define FILE "my/file"
import std.io;   //will not be impacted by the above definition

Важно отметить, что как текущая система препроцессора, так и модули смогут сосуществовать, и заголовки по-прежнему могут использоваться, например, для включения макросов.

Для более подробной информации предлагаю прочитать черновик.

Модули Clang

Clang работает над реализацией модулей, которую можно найти на странице модулей clang . Однако в настоящее время clang не реализует конкретный синтаксис для модулей, то есть ни один из вышеупомянутых синтаксисов не был реализован Clang. Чтобы объяснить это, на странице содержится следующее утверждение:

В настоящее время не существует синтаксиса C или C ++ для объявлений импорта. Clang будет отслеживать предложения модулей в комитете C ++. См. Раздел «Включает как импорт», чтобы узнать, как модули импортируются сегодня.

Основная часть, которая в настоящее время реализуется Clang, - это «язык карты модулей», который позволяет писать карты модулей для существующего кода, который все еще использует файлы заголовков.

Экспорт макросов из модулей

Как упоминалось выше, все еще неясно, будет ли макроэкспорт частью окончательной версии модулей TS . В P0273R1 для экспорта макросов был предложен следующий синтаксис:

#export define MAX(A,B) ((A) > (B)) ? (A) : (B);
lanoxx
источник
2
Обновление от Рапперсвиль 2018 года, есть объединенное предложение от Габриэля душ Рейса и Ричарда Смита, p1103r0. botondballo.wordpress.com/2018/06/20/…
Дуэйн Робинсон
32

Clang - первый компилятор, который начал работать над модулями еще до завершения стандартизации. Документации пока немного, но пример кода можно найти здесь:
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/

Некоторые комментарии от Дугласа Грегора (разработчика, реализующего их):
http://clang-developers.42468.n3.nabble.com/C-modules-td3619936.html

Теоретически вы можете определить набор вспомогательных макросов, таких как begin_module, end_module, import_module, чтобы защитить себя от любых вероятных изменений синтаксиса, которые произойдут в будущем.

РЕДАКТИРОВАТЬ 1:
Дуглас Грегор выпустил презентацию о своей реализации:
http://llvm.org/devmtg/2012-11/Gregor-Modules.pdf?=submit

РЕДАКТИРОВАТЬ 2:
поддержка модуля в clang задокументирована здесь:
http://clang.llvm.org/docs/Modules.html

РЕДАКТИРОВАТЬ 3:
модули теперь также поддерживаются в компиляторе Microsoft C ++: http://blogs.msdn.com/b/vcblog/archive/2015/12/03/c-modules-in-vs-2015-update-1. aspx

за
источник
-39
  1. Потому что это очень большое концептуальное изменение.
  2. В этом нет реальной необходимости, поскольку разделение источников на h / cpp делает работу
  3. Потому что C ++ не определяет, как создаются настоящие «модули» библиотеки. Это оставляет это разработчику компилятора и компоновщику.
  4. «Модули» иногда сильно зависят от платформы, например библиотеки DLL сильно отличаются от общих объектов. Так что объединить эти концепции не так-то просто.
Артём
источник
78
Безусловно, есть необходимость. .h / .cpp - смехотворно плохой и устаревший обходной путь. Модульная система была бы большим изменением, но комитет по стандартизации, очевидно, считает важным.
jalf
13
Модель сборки заголовка - это проблемные модули, которые предназначены для решения, а не решение. Также модули не заменяют библиотеки DLL / SO.
bames53
5
Это неверно: 1. В предложении модуля уделяется особое внимание обеспечению обратной совместимости с существующей системой заголовков, чтобы ничего не сломалось, когда модули будут представлены в будущем. 2. Необходимость уменьшить сложность времени компиляции модуля заголовка с O (M * N) сложности до O (M + N) очень хорошо документирована. 3. Стандарт модуля не будет диктовать, как модули компилируются и связываются, но он добавляет четкую семантику для разделения между частным и публичным API модуля. 4. Стандарт не влияет на двоичный формат DLL или общих объектов.
lanoxx
3
«В этом нет реальной необходимости, так как разделение источников на h / cpp делает работу», так же как и цепная пиление инъекционного пальца, но это не значит, что это не проблема! Достаточно взглянуть на .NET или любой другой новый язык: необходимость упорядочивать вещи определенным образом, чтобы они действительно были видны или правильно построены, - это огромное бремя, которое нужно уйти.
Paulm