LINUX.ORG.RU

Модули... модули? Какие модули?!

 ,


0

5

Привет, ЛОР!

Решил я тут взять C++ для одного своего маленького проекта. Давно ничего сложнее багфиксов в старый код не писал на этом языке по причине его особой не нужности, но тут подумал: «Почему бы и нет?» Естественно, хочу C++ со всеми последними вкусностями, в частности нормальными модулями.

Скажи, ЛОР, как эти модули вообще использовать? Если в рамках моего проекта всё примерно понятно, то использование модулей из сторонних библиотек вызывает много вопросов. Стандартная библиотека, как я понимаю, в модули до сих пор не обёрнута?

Компиляция вот этого примера падает с кучей странных ошибок:

import <iostream>;
import <string>;

std::string s = "Hello World";

int main(void)
{
  std::cout << s << std::endl;
}
$ g++ -std=c++2b -fmodules-ts mod.cc -o mod
In module imported at mod.cc:1:1:
/nix/store/z9jxhrbxm5lxrjpia9xcqjgk990ffr2j-gcc-11.1.0/include/c++/11.1.0/iostream: error: failed to read compiled module: No such file or directory
/nix/store/z9jxhrbxm5lxrjpia9xcqjgk990ffr2j-gcc-11.1.0/include/c++/11.1.0/iostream: note: compiled module file is ‘gcm.cache/./nix/store/z9jxhrbxm5lxrjpia9xcqjgk990ffr2j-gcc-11.1.0/include/c++/11.1.0/iostream.gcm’
/nix/store/z9jxhrbxm5lxrjpia9xcqjgk990ffr2j-gcc-11.1.0/include/c++/11.1.0/iostream: note: imports must be built before being imported
/nix/store/z9jxhrbxm5lxrjpia9xcqjgk990ffr2j-gcc-11.1.0/include/c++/11.1.0/iostream: fatal error: returning to the gate for a mechanical issue
compilation terminated.
$ 
$ clang++ -std=c++2b -fmodules-ts mod.cc -o mod
mod.cc:1:8: error: header file <iostream> (aka '/nix/store/dlni53myj53kx20pi4yhm7p68lw17b07-gcc-10.3.0/include/c++/10.3.0/iostream') cannot be imported because it is not known to be a header unit
import <iostream>;
       ^
mod.cc:2:8: error: header file <string> (aka '/nix/store/dlni53myj53kx20pi4yhm7p68lw17b07-gcc-10.3.0/include/c++/10.3.0/string') cannot be imported because it is not known to be a header unit
import <string>;
       ^
mod.cc:4:1: error: use of undeclared identifier 'std'
std::string s = "Hello World";
^
mod.cc:8:3: error: use of undeclared identifier 'std'
  std::cout << s << std::endl;
  ^
mod.cc:8:21: error: use of undeclared identifier 'std'
  std::cout << s << std::endl;
                    ^
5 errors generated.

GCC и Clang почти последние: 11.1 и 12.0.1. Выходит, модули не работают? Что делать, ЛОР? Отложить C++ до лучших времён?

★★★★★

Последнее исправление: hateyoufeel (всего исправлений: 2)
Ответ на: комментарий от hateyoufeel

Тогда уж перегрузка функций

Согласен, Тьюринг полная система - это всего лишь перегрузка функций и чуть-чуть параметрического полиморфизма.

anonymous
()
Ответ на: комментарий от alysnix

с рантаймом компилятора еще можно смириться. но с рантаймом того, что он делает, компромиссов быть не может.

В смысле, можно смириться? Когда у тебя сборка не самого сложного куска кода не влезает в 4G памяти, это нихрена не нормально.

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от hateyoufeel

Тут можно было бы сделать по-человечески, но это может сломать совместимость, на которую плюсисты так яростно наяривают

Спасибо, один D уже есть.

anonymous
()
Ответ на: комментарий от hateyoufeel

Когда у тебя сборка не самого сложного куска кода не влезает в 4G памяти, это нихрена не нормально.

64 битные компиляторы могут генерировать 32 битный код. Кросс-компиляция…

Зачем собирать именно на клиенте код?

fsb4000 ★★★★★
()
Ответ на: комментарий от filosofia

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

vertexua ★★★★★
()
Ответ на: комментарий от fsb4000

Это давно было. Там был всратый проект с автолулзами вместо нормальной сборки, который надо было похоронить. Кросскомпиляцию сделать было дольше чем немного распилить шаблоны.

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от kvpfs

представь какой ад ты предлагаешь:

Так он уже есть

//any external library ff.hh
void fn(double) {}

//any external library qq.hh
void fn(int) {}
void call() {fn(5.0);}

//user code
#include <ff.hh>
#include <qq.hh>

int main() {call();}
monk ★★★★★
()
Ответ на: комментарий от monk

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

Ещё можно добавить - многопроходной компилятор усложнит анализ кода последовательным парсингом дерева хидеров и превратит в тыкву простые инструменты для автокомплита, которые надёжны, быстро работают и не падают. Да даже обычный поиск по исходнику вверх.

На выходе - усложнения тулинга и компилятора, усложнения чтения исходников без жирного IDE, большая вероятность конфликтов. А ради чего всё? Ради помериться с «современными» языками в бане многопроходностью?

kvpfs ★★
()
Последнее исправление: kvpfs (всего исправлений: 1)
Ответ на: комментарий от kvpfs

а в многопроходном компиляторе получишь просто кучу непротребного кода

Те же яйца только в профиль. Более того, в многопроходном компиляторе уйдёт проблема «угадай, в каком порядке надо поставить включение заголовков».

Ещё можно добавить - многопроходной компилятор усложнит анализ кода последовательным парсингом дерева хидеров и превратит в тыкву простые инструменты для автокомплита, которые надёжны, быстро работают и не падают. Да даже обычный поиск по исходнику вверх.

В 1С анализ кода с автокомплитом прекрасно работает. Зато благодаря многопроходной компиляции можно функции группировать по важности для читателя (сначала основные, потом служебные), а не по дереву зависимостей.

monk ★★★★★
()
Ответ на: комментарий от kvpfs

усложнения чтения исходников без жирного IDE

Упрощение же. Порядок функций можно делать для читателя, а не для компилятора.

monk ★★★★★
()
Ответ на: комментарий от monk

Так он уже есть

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

плюс, надо писать компилируемые хидеры и компилировать их отдельно.

alysnix ★★★
()
Ответ на: комментарий от monk

Упрощение же. Порядок функций можно делать для читателя, а не для компилятора.

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

В 1С анализ кода с автокомплитом прекрасно работает.

Ну это уже какая-то IDE, ей нужно сначала распарсить весь проект. Я же могу открыть вим и получать дефолтный комплит без всякого анализа всего проекта (а если там 100500 строк кода?) и какого-то мусора в виде проектных файлов и тагов, лишь нужное для данной единицы трансляции. Например, пойду исходники ядра править, ждать X минут перед стартом - не вариант, создавать кэш-мусор в проекте - аналогично не хочется.

Те же яйца только в профиль.

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

kvpfs ★★
()
Ответ на: комментарий от kvpfs

Ну это уже какая-то IDE, ей нужно сначала распарсить весь проект.

Почитали бы что нибудь об 1С прежде чем всякую чушь писать …

anonymous
()
Ответ на: комментарий от anonymous

Я попал на кружок 1С-ников? Тем про кресты, и в случае многопроходного компилятора ты не получишь комплит не распарсив проект целиком. А всякие расхваленные Шланг-комплиты показывают полную непригодность в чём-то сложнее продвинутого хелоу ворлда.

kvpfs ★★
()
Ответ на: комментарий от kvpfs

Тем про кресты, и в случае многопроходного компилятора ты не получишь комплит не распарсив проект целиком.

причем тут проект целиком? компилируется единица трансляции - то есть текущий файл со всеми вставленными инклудами. и он или компилируется или нет.

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

а то, чего нет ни там, ни там - видимо быть не может.

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от kvpfs

и потом - сланг нормально автокопмплитит.

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

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

alysnix ★★★
()
Ответ на: комментарий от alysnix

причем тут проект целиком? компилируется единица трансляции - то есть текущий файл со всеми вставленными инклудами. и он или компилируется или нет.

Потому что на многопроходном компиляторе удобно писать такое дерьмо:

//z.hh
void fn();

//x.hh
void call() {fn();}

//main.cc
#include "x.hh"
#include "z.hh"

Однопроходной же заставляет прописывать все инклуды в каждом хидере.

kvpfs ★★
()
Ответ на: комментарий от alysnix

и потом - сланг нормально автокопмплитит.

Ну да, ну да Qt Creator 5.0 (комментарий). И я молчу о том, что забыл об автокомплите задолго до постоянных крешей, только по тагам прыгать ещё хоть как-то можно было. Хорошо, что ГЦЦ не стал вкручивать в себя подобное.

kvpfs ★★
()
Последнее исправление: kvpfs (всего исправлений: 2)
Ответ на: комментарий от kvpfs

Ну да, ну да Qt Creator 5.0 (комментарий).

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

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от kvpfs

Потому что на многопроходном компиляторе удобно писать такое дерьмо:

а такое дерьмо писать не надо. хидеры должны быть раздельно компилируемы.

alysnix ★★★
()
Ответ на: комментарий от kvpfs

Твой код и так скомпилируется. Компилятор может ругнуться на необъявленную функцию, но должен проглотить в итоге.

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от alysnix

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

а такое дерьмо писать не надо. хидеры должны быть раздельно компилируемы.

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

kvpfs ★★
()
Ответ на: комментарий от kvpfs

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

это ерунда какая-то…

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

вот тогда точно наступит ад кромешный

alysnix ★★★
()
Ответ на: комментарий от kvpfs

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

И реализация функций для удобства чтения должна соответствовать порядку деклараций. А не вперемешку с служебными функциями.

Я же могу открыть вим и получать дефолтный комплит без всякого анализа всего проекта

Да ну? Тебе для комплита надо, как минимум, все заголовочные файлы прочитать и разобрать. А вим файл до конца всё равно всегда читает хотя бы чтобы строки посчитать.

monk ★★★★★
()
Ответ на: комментарий от anonymous

А что не так? Вполне себе IDE. Но для дополнения достаточно разобрать текущий модуль и декларации общих модулей.

monk ★★★★★
()
Ответ на: комментарий от kvpfs

Однопроходной же заставляет прописывать все инклуды в каждом хидере.

Зачем?

#include "z.hh"
#include "x.hh"

прекрасно работает.

monk ★★★★★
()
Ответ на: комментарий от alysnix

это ерунда какая-то…

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

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

Просто можно сделать интерфейсный хидер и всё.

kvpfs ★★
()
Ответ на: комментарий от alysnix

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

При таком подходе делают impl.h, в котором лежат все используемые заголовки. А в файле реализации библиотеки всюду всего два включения: lib.h с API и impl.h с зависимостями.

monk ★★★★★
()
Ответ на: комментарий от monk

Т.е. этот гемор с правильным порядком ты не считаешь неудобством? Когда хидеров будет десятки, то это будет интересным интеллектуальным квестом.

kvpfs ★★
()
Ответ на: комментарий от monk

А что не так? Вполне себе IDE. Но для дополнения достаточно разобрать текущий модуль и декларации общих модулей

Было сказано

… ей нужно сначала распарсить весь проект.

Все «на тарелочке» лежит в конфигураторе.
Что касаемо *.h, то чтобы знать данные о функциях нужен парсинг …

Не встречали ли описание формата mxl для 1С 8.x?
Можно конечно расковырять, но вдруг уже кто-то эту работу сделал.
Для 1С 7.7 обеспечил возможность работы с mxl /свою, а не Йокселя/.
Все Ok и много больше функциональности.
Хотелось бы и для 1С 8.x API разработать.

Если честно говоря, то все эти mxl - «лаба», но ПОЛЕЗНАЯ …

anonymous
()
Ответ на: комментарий от kvpfs

Такое же неудобство, как правильный порядок функций в файле. Привыкнуть можно, но проще, когда компилятор двухпроходный.

monk ★★★★★
()

Шутка

Модули, модули, модули, модули, модули, модули, модули, модули, …

Вы че?   
Какие модули?!
anonymous
()
Ответ на: комментарий от anonymous

Все «на тарелочке» лежит в конфигураторе.

Там такой же текст. И он также на лету разбирается.

Не встречали ли описание формата mxl для 1С 8.x?

Нет. Если просто выдрать данные, то что-то вроде https://github.com/khorevaa/v8storage/blob/develop/src/%D0%9A%D0%BB%D0%B0%D1%81%D1%81%D1%8B/internal/ripper/%D0%9A%D0%BB%D0%B0%D1%81%D1%81%D1%8B/%D0%9F%D0%B0%D1%80%D1%81%D0%B5%D1%80%D0%9E%D1%82%D1%87%D0%B5%D1%82%D0%B0%D0%A5%D1%80%D0%B0%D0%BD%D0%B8%D0%BB%D0%B8%D1%89%D0%B0.os

monk ★★★★★
()
Ответ на: комментарий от monk

Там такой же текст. И он также на лету разбирается.

В конфигураторе в некоторых разделах имеются данные об глобальных функциях, …
У компилятора C++ таких метаданных нет, ему нужно парсить.
Что касаемо bsl, то здесь да парсинг нужен, но при этом парсер сопряжен с метаданными, которые уже имеются в конфигураторе …

За URL

Спасибо!  

Шас буду смотреть …

anonymous
()
Ответ на: комментарий от anonymous

У компилятора C++ таких метаданных нет, ему нужно парсить.

У любой IDE есть прекомпилированные заголовки, кэшированные метаданные и всё такое.

monk ★★★★★
()
Ответ на: комментарий от monk

У любой IDE есть прекомпилированные заголовки, кэшированные метаданные и всё такое.

Это да, но и различий много …

anonymous
()
Ответ на: комментарий от Benis

Как будто кто-то кроме виндузятников пользуется IDE для C++. Все пишут в vim/emacs.

Это многое говорит о «всех». Без IDE удобно писать только на С с классами.

Siborgium ★★★★★
()
Ответ на: комментарий от Siborgium

http://rsdn.org/forum/cpp/7190309.flat Re: Си с классами vs C++

Интересный коммент

>те когда это еще Си с классами, а вот после этого стал уже С++

Очень просто, когда не пытаются выпихнуть обработку данных в complile-time и использовать шаблонные не поназначению, а  
просто пишут код которые решает поставленнуюю задачу, вы без иде можете сказать какой тип у переменной — это C с классами.
А вот когда у вас кругом header-only, шаблон на шалоне, везде где только можно move-семантика,   
смарт поинтеры, для компиляции нужно топовое железо, огромное количество кода которой не решает задау, а делает "удобнее",   
"правильнее" и "всеобъемлюще", при этом создаётся больше проблем чем решается и любая незначительная опечатка приводит к  
неочевидной ошибке компиляции которую надо еще самому долго вкуривать — вот тут уже следует насторажиться видимо современный C++ где-то рядом.
anonymous
()
Ответ на: комментарий от Siborgium

Ты не прав, если тебе неудобно писать без IDE, то ты инвалид.

Benis
()
Ответ на: комментарий от anonymous

Поговорю с цитатой.

Очень просто, когда не пытаются выпихнуть обработку данных в complile-time

Т.е. когда не пытаются написать производительный код.

и использовать шаблонные не поназначению

Назначение шаблонов определяет программист. Впрочем, доля правды здесь есть – в современном С++ шаблоны нужны куда реже, так как есть вменяемый constexpr.

вы без иде можете сказать какой тип у переменной

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

везде где только можно move-семантика,

Без move-семантики нельзя выразить перемещение в общем случае. Возвращаемся к вопросу производительности.

для компиляции нужно топовое железо

Никого, кроме гентушников и прочих 1% от 1% не волнует требуемое для компиляции железо. Людей волнует железо, требуемое для работы программы.

огромное количество кода которой не решает задау, а делает «удобнее», «правильнее» и «всеобъемлюще»

Задача: как можно больше проверок перенести в compile-time. Нетрудно заметить, что цель достигается. Кавычки, кстати, лишние.

при этом создаётся больше проблем чем решается

Аргументы?

и любая незначительная опечатка приводит к неочевидной ошибке компиляции которую надо еще самому долго вкуривать

Какое поведение ожидается?

вот тут уже следует насторажиться видимо современный C++ где-то рядом

На этом можно заканчивать.

Siborgium ★★★★★
()
Ответ на: комментарий от Pavval

Модули никаким образом не влияют на время компиляции, жертва пропаганды. Как максимум тем, что у тебя будет pch по дефолту.

anonymous
()
Ответ на: комментарий от Pavval

С модулями такого не будет.

Будет. Модуль - это хедер. Там для макака есть какое-то не-хедер огрызки, но это мало что меняет.

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

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

предкомпилируется то, что его инклюдит.

anonymous
()
Ответ на: комментарий от Siborgium

Никого, кроме гентушников и прочих 1% от 1% не волнует требуемое для компиляции железо. Людей волнует железо, требуемое для работы программы.

Вот тут ты сильно ошибаешься. Меня как разработчика очень волнует время сборки, потому что это в итоге выливается в скорость разработки софта.

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Тут и без тебя знали, что зависимые имена в шаблонах - исключение. Вот если подобное покажешь без зависимых имён, то дело другое.

kvpfs ★★
()
Ответ на: комментарий от anonymous

Возьми любой небольшой проект и сделай g++ -E | wc, там спокойно будет столько. Тут можно спорить об объективности, да, но это в любом случае надо парсить.

ЗЫ: ну не любой конечно, а ho, чтобы была одна единица трансляции.

kvpfs ★★
()
Последнее исправление: kvpfs (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.