LINUX.ORG.RU

Си с классами

 , ,


0

7

Тупнячка принёс, извиняйте.

Начинаю проект (личный), выбираю на чём писать: C или C++.

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

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

Насколько такой суперсет C / сабсет C++ ака «Си с классами» может быть кошерен?

Объясните почему так делать не стоит, либо даже наоборот, предложите уже существующие сабсеты плюсов, которые можно перенять.

Ответ на: комментарий от RazrFalcon

соорудите мне std::vector

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

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

На форуме поселился фанат Оберона. Хорошо, прям как в благословенных 00-х. Ностальжи!

wandrien ★★
()
Ответ на: комментарий от RazrFalcon
static const Derived derived;
std::vector<std::reference_wrapper<const Base>> v = {
  std::cref(derived)
};

чё тебе ещё соорудить? давай заказывай, у нас же тут стол заказов.

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

Вопросы уровня «соглашайтесь со мной или вон»?

Вы взялись рвать шаблоны. Но каким-то только вам понятным методом. Отсюда просьбы пояснить как именно вы эти самые шаблоны рвать собрались.

Не более того.

Я сдаюсь.

Флакон традиционно порвался. Рот зачем было открывать, если вопрос не вам адресовался? Но это риторический вопрос.

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

Вы победили. Я сдаюсь.

пакеда.

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

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

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

Следите за нитью разговора. Динамический конечно через vtable. Тут всё как в плюсах, только явно.

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

Статика, полиморфизм, без vtable. Всё как надо.

Не, так не пойдет.

Давай сооружай вектор из объектов, и чтобы эти объекты были статическими, а не динамичесие (динамически аллоцированные) объекты с изменяемым размером, и чтоб не содержали vtable.

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

разницы нет между C++ и Rust нет

В том то и дело. Что эти заумные закорючки в rust (&, mut, dyn, box, unbox и их сочетания) - это все лишь (не)сахар над такими же закорючками в c++ (&, *, std::smart_ptr и др). Разница в том, что неоднозначный анализатор borrow check насильно включен на уроне генерирования ошибок компиляциии. Вот вся разница. И эту разницу можно легко компенсировать, обмазавшись такими же неоднозначными статическими анализаторами для с++.

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

Ну а по делу высера есть что возразить, мне просто интересно.

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

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

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

anonymous
()

По треду создаётся впечатление что понятного и читабельного кода на плюсах здесь почти никто не пишет.

Если коротко - наиболее эффективно улучшающее C подмножество плюсов - C++ без приватности, почти без своих шаблонов, без своих методов, без своих namespace, без наследования и виртуальности.

Но обязательно c автоматическим управлением ресурсов - RAII и готовыми классами из stl или boost, в т.ч. типизированными путями std::filesystem::path

Исключения - использовать для необрабатываемых ошибок, ловить только в считынах единицах мест - чтоб показать сообщение что «всё упало, завершаемся». Свои можно не делать, хватит std::logic_error, std::runtime_error

Почему именно так? Потому что все фичи, предлагаемые к НЕиспользвованию - по факту лишь направляют разработчика. То есть если УЖЕ есть умение не стрелять в ногу в C - то замена в хорошем C-коде функций на методы, макросов на шаблоны и длинных имён на namespace - даст незначительное повышение читабельности.

А вот использование RAII и stl-ных классов - делает код компатнее и более читабельным.

Насчёт RAII в отношении памяти более подробно.

  • Переменная на куче - 95% std::make_unique
  • Переменная на куче которая хрен знает когда удалится (плохой дизайн)- 4% std::make_shared
  • malloc, free, new, delete, и boost::intrusive_ptr - оставшиеся 1% случаев.

Голые указатели никогда не должны владеть памятью. (Зачем?)

массив неизвестнной заранее длинны в 99% случаев через std::vector.

Нетривиальные коснтрукторы/деструкторы у структур - делать только в случае, если это обёртка над чем-то обеспечивающая RAII. И 1000 раз подумать, там есть много путей накосячить.

А вот структуры просто содержащие поля стандартных типов, классов и других структур - без проблем. Не передавать int x, int y, делать struct Point, это собственно и в C так.

И, да, в production я пишу и с теми фичами, которые тут забраковал. Они улучшают читабельность, но не столь сильно как RAII и stl, время на изучение окупится очень не бытсро. А RAII и понадобившиеся подмножество stl/boost - окупится очень быстро.

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

box, unbox

Вам приснилось. Нет такого. И речь изначально шла про трейты, аля концепты из C++20.

И эту разницу можно легко компенсировать

Ага, заодно ADT, паттерн матчин и выражения мне запилите. Я не уверен, что даже трейты можно повторить в С++20.

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

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

+1

Раст мог еще выглядеть убедительно, если бы C++ продолжал стагнировать, а растеры смогли бы вкатить Раст как промышленный стандарт с чёткой спецификацией, а не с питон-стайл «реализация является спецификацией».

Но современный C++ делает эти потуги ненужными.

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

Но современный C++ делает потуги его изучить ненужными.

пофиксил во имя справедливости.

Раст, к сожалению, судя по всему ждёт судьба лиспа с его lisp curse. И дело даже не в стандарте с спецификацией, её не будет пока не будут строго определны правила по которым работает borrow checker, а это произойдёт скорее всего никогда.

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

С++ все равно не угонится за растом, но попытки неплохие.

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

дело в том, что там где хаос порядка нет, его нет и в С++, но этот ублюбок уже плотно прижился на теле IT, сможет ли такой же фокус провернуть маленькая горстка RUSTрельных жертв? Думаю, весьма сомнительно, не продавят ни хватит энтузиазма )

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

trait != trait object

Дело в том, что trait object как раз описывает как хранится trait.

Ты покажешь vector из traits? Без аллокаций и vtable? Посмотрим, как там решили вопросы std::variant с генерацией vtable в статике.

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

Так мономорфизация жеж. Параметр типа T с ограничением в виде трейта превращается в конкретный тип на этапе компиляции.

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

Ну Rust хорош сам по себе, как технология, а не в силу того, что кто-то куда-то его двигает.

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

Тип T надо где-то хранить (type_t type). Естественно сами данные тоже надо где-то хранить (void* data). И таблицу «мономорфов» тоже надо где-то хранить (vtable).

anonymous
()

Про что проект-то хоть?

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

Хранить на этапе компиляции имеете ввиду?

Хранить vtable - значит у тебя должно быть отображение (type, trait_func_index) -> func.

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

Так вы не ответили на вопрос, на каком этапе хранить это отображение? Если во время выполнения программы, то этого в Rust нет (для параметрического полиморфизма). Во время выполнения программа ничего не знает о типах, трейтах и прочем.

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

Во время выполнения программа ничего не знает о типах, трейтах и прочем.

И вытаскивает эти знания при помощи libastral?

Во время выполнения программы раст знает и тип и вызываемую функцию, и вытаскивает из таблицы соответствия (vtable) адрес конкретной реализации функции трейта для конкретного типа.

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

На годболте есть Rust, можешь поиграться, может поймёшь как там Rust что делает, возможно так будет быстрее понять, чем спрашивать, всё равно тут никто в Rust не разбирается, как там что работает…

https://rust.godbolt.org/z/PrMP71 (131 строка ассемблера)

В каждом элементе вектора из трейта с одной функцией хранит

  1. Адрес функции деструктора

  2. Какие-то два числа

  3. Адрес метода трейта.

 .quad   core::ptr::drop_in_place
        .quad   0
        .quad   1
        .quad   <example::Cat as example::Animal>::say
fsb4000 ★★★★★
()
Последнее исправление: fsb4000 (всего исправлений: 2)
Ответ на: комментарий от anonymous

Еще раз: на этапе компиляции в следствии мономорфизации параметрический полиморфизм превращается в ad-hoc-полиморфизм, то есть генерируются конкретные реализации для конкретных используемых типов, а вся информация об обобщении стирается: https://godbolt.org/z/zcWj55

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

131 строка ассемблера

Делать мне нечего, кроме как ассемблер читать. Без этого знаю как это работает (должно). На 100% уверен, что std::visit (аналог трейтов) будет работать намного быстрее.

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

Конечно, потому что вы используете трейт-объекты, а не параметрический полиморфизм.

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

Ты неоптимизированный вариант показывай, а лучше даже неоптимизированный llvm байт-код. А не то что llvm наоптимизировал, сам rust-то практически туп и в оптимизации на уровне языка ничего не умеет.

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

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

Вам сказали, что trait != trait object. Хотите использовать trait object и динамическую диспетчеризацию? Пожалуйста. Только не надо их совать тем, кто обходится одними trait в параметрическом полиморфизме со статической диспетчеризацией.

fn foo() -> Vec<dyn Trait> { ... }
fn foo<T: Trait>() -> Vec<T> { ... }

Чувствуете разницу?

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

Чувствуете разницу?

Убери оптимизацию ‘-O’ из флагов для компилятора и почувствуй разницу.

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

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

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

А для кого std filesystem?

Не могу ничего сказать про него, да, штука полезная, но у меня все взаимодействие с диском - запись логов и то сейчас уже логи пишутся через grpc.

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

На этом принципиальном согласии можно было и остановиться :)

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

eao197 ★★★★★
()

Бери C++ и пиши. Однако, если тебе не нужно C++, то бери Python3.7+ или C#, если религия позволяет.

ЗЫ

Если мсье знает толк, то можно взять Rust, но надо познать толк и быть готовым к нему.

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

Опа как царь-то жопой заелозил. Уже и оптимизацию ему выключи и байткод ему не кошерный.

Прописываю Царю глистогонное!

Dark_SavanT ★★★★★
()

Начинаю проект (личный), выбираю на чём писать: C или C++

Хочешь, рецепт борща дам?

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

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

Я не уверен, что даже трейты можно повторить в С++20.

Это просто частичная специализация + проверка что специлизация существует, транслируется на С++, почти строчка в строчку:

https://godbolt.org/z/8Gn86v

Это можно повторить даже на С++98(более многословно, но шаблоны Тюринг полны, так что возможно всё…)

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