Модулі C ++ - чому їх видалили з C ++ 0x? Чи повернуться вони згодом?


110

Я щойно відкрив цю стару С ++ 0x чернетку про модулі в C ++ 0x.

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

Це виглядає як справді чудова функція.

Але моє запитання: чому вони видалили його з C ++ 0x? Це було через занадто багато технічних труднощів? Нестача часу? А ви думаєте, що вони розглядають можливість роботи над нею для останньої версії C ++?

Відповіді:


70

Згідно зі стані еволюції C ++ (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 року).
  • Колективна команда опублікувала другу редакцію їх змін: P0273R1 (жовтень 2016 р.).

Наступні повідомлення в блозі містять короткий виклад засідань зі стандартів, зокрема короткий опис поточного стану проекту модулів:

Оновлення: Як пояснено у звіті про поїздку Kona, до якого я посилався вище, наразі є дві конкуруючі пропозиції: одна від 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 ++. Кланг відстежує пропозицію модулів у комітеті C ++. Дивіться розділ Включає як імпорт, щоб побачити, як сьогодні імпортуються модулі.

Основна частина, яку зараз реалізує Кланг, - це "Мова модульної карти", яка дозволяє писати модульні карти для існуючого коду, який все ще використовує файли заголовків.

Експорт макросів з модулів

Як було сказано вище, поки не ясно, чи буде макроекспорт входити до кінцевих модулів ТС . У P0273R1 для експорту макросів був запропонований наступний синтаксис:

#export define MAX(A,B) ((A) > (B)) ? (A) : (B);

2
Оновлення від Rapperswil 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

Теоретично ви можете визначити купу макросів-помічників, таких як start_module, end_module, import_module, щоб захистити себе від будь-яких ймовірних змін у синтаксисі, які надійдуть у майбутньому.

EDIT 1:
Дуглас Грегор випустив презентацію про свою реалізацію:
http://llvm.org/devmtg/2012-11/Gregor-Modules.pdf?=submit

EDIT 2:
Підтримка модуля в clang була задокументована тут:
http://clang.llvm.org/docs/Modules.html

EDIT 3:
Модулі тепер підтримуються і в компіляторі C ++ Microsoft: http://blogs.msdn.com/b/vcblog/archive/2015/12/03/c-modules-in-vs-2015-update-1. асп


-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 або будь-який інший новіший язик, тому що замовляти речі певним чином просто так, щоб вони насправді були помітні або будувались правильно, це величезний тягар, який повинен пройти.
Паульм
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.