LINUX.ORG.RU

юнионы в C++

 


1

4

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

Даже интересует не столько то, насколько они используются в существующих программах, а есть ли примеры программ, где хорошие средства плюсов сконсолидировались и поставили заслон от опасных конструкций Си, позволив полностью избежать их использования и избавиться от типичных ошибок Си. Можно ли так написать что-то существенно сложное? Сделано ли это в любимых библиотеках (Буст, QT и иже с ними)? Вторая часть вопроса - это неопределённое поведение. В Си его много. Это подаётся как фича, но с точки зрения безопасности это дыра. Меньше ли неопределённого поведения в С++?

Есть две полярные точки зрения на вопрос:

а) С++ перекрывает Си, поэтому там всё сделано по-другому, поэтому безопасность выше б) С++ - наследник Си и в целом наследует его недостатки.

Поскольку я мало пишу на Си и ещё меньше на Си++, у меня нет сложившегося мнения на эту тему. А у ЛОРа наверняка есть мнение, даже несколько.

★★★★★

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

Я и до сих пор думаю, что если взять какое-то определённое подмножество плюсов, выбранное истинным Гуру, то может быть оно так и будет

Чем больше таких людей как вы, тем больше мы стоим как специалисты. Посему - я только за.

и в ней вообще не будет сишных библиотек.

Гхм. Мы забыли где находимся?

И кроме того, практика у каждого своя.

Это правда.

Моего самомнения явно недостаточно

Даже не знаю как реагировать.

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

Всё новое - нужно. Это, типа, аксиома.

Ага, новые штаммы ковида, например.

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

Вот взять, к примеру, науку под названием «метрология». Давайте раз в год придумывать новые системы единиц измерения и способы их записи - вдруг удобненько получится. Или стандарты резьбы давайте переизобретать, например. С пятиугольным профилем же еще нет вроде?

Старые [уже распространённые в области] языки ведь никто не отнимает, и всегда можно написать биндинги.

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

Я за латиницу, на выразительную мощь ЯП это не влияет.

Я тоже, то был сарказм с конкретным адресатом.

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

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

А если найду?

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

Новые языки не нужны уже очень, очень, ОЧЕНЬ много лет

Конечно нужны. Отдельный программист не решает все типы задач, которые позволяет решить C++, например. Решается подмножество. А для подмножества можно создать DSL, который будет лаконичнее описывать решаемую задачу.

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

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

У меня вопрос вызвала эта цитата:

у них всех был какой-то фатальный недостаток

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

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

Погуглите незабвенную классику про «нашли фатальный недостаток – его писали не мы».

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

Вы у себя в коде используете
#define vl volatile
и вручную написанные функции по 350 строк длиной.
Возможно, для вас это нормально, а для меня – это откровенный говнокод, а автор криворукий говнокодер

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

Мне нужен, я использую, время от времени компилятор бьет мне по рукам и предотвращает ошибки

Я ни разу не спорю, что благодаря const возможно отловить некоторое число ошибок. Малое — потому что проверка очень куцая, есть много сценариев (которые я упомянул и которые избежели авторы стандартной либы), в которых она вообще не работает, как то контейнеры-ссылки. Я спорю именно с тем, что это количество настолько исчезающе мало, что не окупается дополнительной ментальной нагрузкой, вызванной необходимостью ублажать компилятор и копипастить функции для создания const/non-const перегрузок. Итоговый результат — плюс-минус ноль.

Что характерно, даже в мемуарах 1994 года Страуструп лишь однажды вскользь проронил, что const помогает отлавливать какие-то там ошибки. Основная цель модификатора const, которую он под разным соусом описывает в нескольких разрозненных разделах — это создание объектов-констант: их нужно как-то инициализировать, то есть, вызывать консторкторы и менять поля, после чего объект становится read-only, а потом еще и деструкторы должны как-то отработать, и снова объект как бы перестается быть константным. Как можно заметить, уже в своей первоначальной форме это был трешак со временными снятиями константности. Но это были именно константы, а не константные ссылки.

Грепание по сорцам Cfront 1.0 подтверждает мою идею — почти все использования const являются типом const char *, то есть, указатель на строковую константу. У константных объектов методы были те же, что у неконстант — константные методы появились заметно позже, где-то ближе ко второй версии в 1989 году, где константные методы уже присутствовали.

Идею «заражающего» const в составных объектах распространили авторы STL, стандартной либы, и просто случайные коучи-продажники. В 1994 году у Страуструпа была только идея пары перегруженных функций (11.2.1. Fine-grain Resolution):
char* strtok(char*, const char*)
const char* strtok(const char*, const char*)
то есть, опять-таки, строго примитивные типы.

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

А если еще вспомнить, что стандарты часто пишутся кретинами, которые больше ничего другого не умеют делать — то сразу всё встает на свои места. Конечно, картина испортилась, когда писанием стандартов C++ начал руководить гугл. А когда стандарты по JS начал писать Дуглас Крокфорд — JS внезапно стал адекватным языком и заполонил.

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

Ну как ты сделаешь иначе список const char *? Список и его значение имеют абсолютно разные типы и к ним могут предъявляться разные требования — не нужно шланговать.

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

Для begin есть две перегрузки: non-const и const. А cbegin - это для того, чтобы вызывать const перегрузку begin, без приведения (каста) объекта к ссылке на const-qualified тип

Так а я о чем? Const — это про то, чтобы реализацию одного метода писать в трех экземплярах. А еще я о том, что у constexpr такого изъяна нет.

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

[[nodiscard]] auto get_second(const Container & from) {...}

Ололошеньки, подводные камни на самом берегу: а что, если кто-то поменяет возвращаемое по ссылке non-const значение? У нас же const Container &? Вот только я написал про путаницу, и сразу же получил в ответ подтверждающий пример.

В конкретном прикладном коде вы можете написать только то, что вам нужно здесь и сейчас

Жму руку, только это значит «перестать лепить сложные превращения const ссылок», и это почти то, о чем я которую страницу пишу. Не только лишь все понимают, что нечитаемые библиотеки, подобные STL, очень трудозатратны при поддержке, и в случае STL это нивелируется лишь тем, что поддерживаю ее не я.

Во-вторых, проблема с необходимостью делать перегрузки методов для не-const, const, а так же для rvalue references случаев в C++ известна

Да, я совсем забыл про rvalue reference, с ним еще больше методов нужно копипастить.

И очень долго время под соусом const существовало три независимых вещи:

Во-первых, странная классификация, в очередной раз демонстрирующая что у вас в башке говно плещется. Первый случай из вашей классификации в C++ никогда const-ом не был

Как мило, ответный слив дискусии. Я не намерен её тут вытягивать: свое мнение я высказал, а претензий по существу не вижу.

Не может. vector<T> – это вариация на тему T[]. Соответственно, когда у вас есть const T a[40], то операция a[23]=0 является попыткой поменять a

Оно является только тем, чем является — вызовом оператора T[], оно ничего не меняет. Это потом уже за уши притянута массивоподобная семантика. Хотя, почему-то «cout << » не смещает биты у объекта cout.

если у вас T – это нечто вроде:
struct T {
std::string * str_;
};
то вы можете написать a[23].str_->assign(«abc»), потому что в таком случае a не меняется, в нем как были исходные значения, так они и остались

Да-да, внутри std::vector тоже есть ссылка на массив, но константность заражает данные по этой ссылке — так называемая «логическая константность». Стоит признать, что все-таки контейнеры STL больше построены именно вокруг логической константности, а не бинарной. Но эта логическая константность тяжела в реализации, но даже после больших усилий по реализации она протекает.

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

А если найду?

Давай.

class A { virtual B* create(); };

class B { virtual A* create(); };

class AC : public A { BC* create() override; };

class BC : public B { AC* create() override; };

Как?

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

И по этому идёт падение популярности Go?
Или потому что его чуть-чуть усложнили, добавив необходимое, и желающих его изучить сразу стало сразу меньше?

Stackoverflow говорит, что рост популярности на 10% с 2020 на 2021. Это слабовато, конечно, но я не вижу здесь вины ЯП. IT само по себе сопротивляется любому новшеству, и нужна какая-то новая ниша, чтобы новая технология в нее упала — иначе вся индустрия продолжит еще 30 лет лепить костыли на безнадежно устаревшем инструменте, как это уже происходило несчетное число раз.

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

Написали Rust. И как, помогло?

Скорее нет, чем да, потому что Rust повторил слишком много изъянов C++.

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

Stackoverflow говорит, что рост популярности на 10% с 2020 на 2021.

Это те кто уже подсел закопались.

А вот Tiobe говорит о падении на 19% (относительных) с начала 2021 на начало 2022.

Упало до значение 0.95% (абсолютных).

А это как раз те, кто думает посмотреть в сторону go.

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

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

Меньше 2 на мутабельную строку выделять не получится

Имелась в виду мутабельная строка со счетчиком ссылок.

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

какая еще идеология «STL auto», auto - это вывод типа переменной по выражению. просто синт. сахар такой, чтобы явно тип не писать

Я опечатался, ок? По твоей интерпретации получается бред, куда не отнеси STL auto: либо «должно стать» без подлежащего, либо идеология без уточнения, что это за идеология. Очевидно, что корректным является третий вариант постановки запятой.

и с какой стати оно должно стать указателем на неизменяемое значение?

А с какой стати vector::at() на константном векторе должно возвращать ссылку на константу? А если сделать в структуре поле optional<string>, то обращение к нему будет выглядеть как ссылка (optional считывается через оператор «*» и "->"), но при этом по факту будет копированием — это третий уникальный способ использования синтаксиса указателей.

На мой неискушенный взгляд это называется «БАРДАК», но плюсовики за годы научились видеть в этом какой-то свой смысл... как и видеть смысл в каждом из одиннадцати способов инициализации.

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

Основная проблема крестов в том, что все программисты почему-то считают себя умными. А основной объем кода пишут как раз именно те, которым пока рановато

У программистов с возрастом не становится больше рук или голов. Если я напишу на своих самых знакомых ЯП код «на пределе», то через полгода-год выяснится, что я не понимаю, как он работает. В этом и отличается нуб от бывалого — бывалый знает, что не сможет прочитать код, что код точно упадет, что он не сможет его отладить, что архитектура точно говно, какой бы она ни была. И тогда он пытается минимизировать последствия этих проблему, упрощая код, не пытаясь создавать архитектуру там, где ей рано быть, и создавая более одной линии защиты от дурака, коим он непременно станет сам с ближайшем будущем.

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

Вы реально думаете что const это про отлов ошибок?

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

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

что я не понимаю, как он работает

Так и запишем. Ответьте на мой прямой предыдущий вопрос пожалуйста. Можно даже без полотенец. Там «да/нет» вполне уместно.

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

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

Зато валом дебилоидов, которые пишут книжки и учат правильно писать на плюсах, больше, чем нужно. Тот же Скот Мейерс, например, который издал целую серию книжек «как не нужно писать на C++». Я снова и снова с удивлением вспоминаю мое первое знакомство с плюсами, когда я читал книжки, статьи, и там была спрошная чушь про наследования и виртуальные методы, или какие-то подводные камни взаимодействия фич, какие-нибудь хитрожопые copy-elision в неожиданных местах, или ёлочки из шаблонов на целую страницу — я это читал и думал «на это можно что-то работоспособное написать?». Даже сейчас, когда я пишу на плюсах, у меня не поменялось мнение — я понимаю, что был прав, и да, нельзя на этом писать что-то работоспособное за вменяемое время. Но у меня не было старшего товарища, который бы мне пояснил ситуацию.

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

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

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

я не вижу перспектив для const

Как во времена моей юности любил поговаривать один из моих преподавателей: «да Вы батенька - дурачок, ду-ра-чок». Вы походу даже примерно не понимаете зачем и почему он в языке появился.

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

Так и запишем. Ответьте на мой прямой предыдущий вопрос пожалуйста. Можно даже без полотенец. Там «да/нет» вполне уместно

Оба ответы неправильны (да и нет), потому что вопрос изначально поставлен в духе «есть два стула..». Помогает ли const делать меньше ошибок по сравнению с #define? Да. Является ли единственным назначением const отлов ошибок? Нет. Это уже не говоря о том, что, как я писал выше
юнионы в C++ (комментарий)
у слова «const» в C++ есть три различных назначения — ты про какое из них спрашиваешь?

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

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

Теперь этот «шедевр» вам удалить не удастся. У меня всё.

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

Можно список недостатков, которые повторены в Расте?

Из того, что с ходу вспоминается: медленная компиляция; переусложненность как минимум двумя независимыми подъязыками (по аналогии с C и C++); переусложенная система типов и статичных проверок, по сравнению с которыми const просто нервно курит в сторонке, где ради перфекционистской, но недостижимой на 100% цели безупречно корректной работы с указателями, принесена в жертву простота описания и гарантии корректности логики, то есть, ты большую часть времени будешь читать вспомогательные конструкции, а не логику.

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

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

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

Теперь этот «шедевр» вам удалить не удастся. У меня всё

И у меня всё, мне добавить к сказанному нечего.

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

у слова «const» в C++ есть три различных назначения — ты про какое из них спрашиваешь?

Давайте называть вещи своими именами. Это называется «keyword». И давайте лучше «static» обсудим - там интересней.

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

Основная ошибка создателей - попытка создания языка, который делает всё

den73 , это вдогонку про «повторённые недостатки Rust».

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

Давайте называть вещи своими именами. Это называется «keyword». И давайте лучше «static» обсудим - там интересней

Статик изначально натягивался для абсолютно разных функций. В то же время, const всегда является модификатором типа, и даже когда речь идет про константный метод, подразумевается const T* const this.

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

Новые языки не нужны уже очень, очень, ОЧЕНЬ много лет. Нужны реализации протоколов, парсеры форматов, мультимедия-либы, гуйцы, коннекторы БД, IPC и прочие ЖБИ для прикладухи

Давай выкрутим цинизм на максимум и начнем резать правду-матку: ничего из перечисленного тобой не нужно, нужны просто индусы, которые будут писать очередной никому не нужный сервис/вебсайт/парашачейн за миску риса, чтобы этот проект в итоге банкротился, но некоторые участники оного оставались в плюсах, а другие — в минусах. Это часть того самого «перераспределения ресурсов», смыслом которого являлась вся англосаксонская экономика последних 200-300 лет.

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

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

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

Теперь можно писать статью на хабре «кресты - говно», чтобы потом какие-нибудь дятлы ее регулярно таскали обратно на ЛОР

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

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

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

Цель правильная, кибернетическая. Только надо осознавать, что за ней следует.

Товарищ! Смелее приближай технологическую сингулярность!

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

В то же время, const всегда является модификатором типа

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

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

Зачем это? Я за латиницу, на выразительную мощь ЯП это не влияет. Комменты тоже на английском писать

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

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

И у меня всё, мне добавить к сказанному нечего.

У меня появляется надежда? Или вы намерены продолжать нести свой поток сознания в массы?

bugfixer ★★ ()

Параграф раз:

Пишу телегу против плюсов

Параграф два:

Поскольку я мало пишу на Си и ещё меньше на Си++

Ржал пацталом. «Не читал, но осуждаю!» - прямо классика.

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

А то и к психиатру, причем в первую очередь, до психолога.

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

Основная ошибка создателей - попытка создания языка, который делает всё

den73 , это вдогонку про «повторённые недостатки Rust»

Согласен с точностью до наоборот. Если язык пытается быть таким мета-языком для DSL (\forall domain known by meta-lang authors), то это похвально

И C++, и Rust позволяют писать всё, что требуется. Для этого нужно 1) высокоуровневые примитивы для низкоуровневых штук, 2) намёки на zero-cost и 3) metaprogramming

Без (3) нельзя удобно сделать (1) и (2)


metaprogramming в C++ «ну норм», в Rust вроде получше (но тут мне тоже напели на ЛОРе)

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

Меньше 2 на мутабельную строку выделять не получится в принципе без дополнительных приседаний – со всеми оптимизациями

Хм-м-м, если я правильно понял, о чем ты, то тогда мой вариант будет «три-четыре». Потому что теоретический минимум в «2 блока» — это указатель и сами данные. Дальше уже в shared_ptr и string возникают бесполезные вспомогательные блоки.

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

Разработчики стандартов — очень странные люди, потому что иногда они ради 3% производительности накладывают вето на интроспекцию, а в другой момент для них хэш-таблицы с косвенным доступом к значениям являются «достаточно производительными». Хотя на самом деле нифига не являются, они намного медленнее интрузивных, и вообще весь смысл технологии хэш-таблиц как оптимизации заключается в том, чтобы не иметь косвенного доступа совсем или почти совсем.

Выполнив некорректную последовательность финализаторов, GC может выстрелить себе в ногу

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

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

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

Нет, это не сахарок для расчета выравнивания структуры

Ну, и какие еще есть функции у union, которых нет у каста указателя?

С вообще не для высокоуровневого программирования

Ну я рад, что мы согласны в том, что Си — это тупо портируемый ассемблер.

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

Ну я рад, что мы согласны в том, что Си — это тупо портируемый ассемблер

Кто-то где-то обещал больше?

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

metaprogramming в C++ «ну норм»

Надо бы раскрыть этот тезис.

Мне в meta-C++ не хватает одной простой вещи: возможностью произвольно управлять текстом (AST?) тела функции. Часть данных, используемых в выражениях, я знаю в compile-time — их надо подставить сразу числами. Выражения могут быть произвольной сложности и содержать любые инструкции. Циклы с compile-time параметрами хочу уметь гибко анроллить. И т.д.

Да, я умею это делать на чистом C++. Возможно, недостаточно искусно. Но для сложных случаев всё равно приходилось переходить на внешнюю генерилку c++-кода на python. Такой дуэт мне тоже не нравится, но он по-крайней мере переносит управление всей compile-time code generation логикой на уровень выше, что избавляет, например, от траханья со связкой (шаблоны, constexpr, pragma unroll), ибо всё вместе это использовать — трудно, а по отдельности — не хватает

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

class A { virtual B* create(); };
class B { virtual A* create(); };
class AC : public A { BC* create() override; };
class BC : public B { AC* create() override; };

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

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

А вот Tiobe говорит о падении на 19% (относительных) с начала 2021 на начало 2022

У тиобы график вообще плащет как попало, там даже не 19%, а намного больше. Вверх, потом вниз, потом снова вверх, и так далее.

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

Когда я вспоминаю себя новичкому, то я думаю, что мне было бы решительно пофигу, какие фактические «сложности» есть в языке — меня волновало только то, насколько мне просто начать на нем писать работающий софт.

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

^

den73: для приложений несравнимо комфортнее использовать лисп

AntonI: Зависит от приложений. У нас в HPC для некоторых задач вообще активно используется генерация плюсового кода на питоне. Я уже писал, что задачи очень разные, где то плюсы ненужны, где то без них никак. Где и почему без них никак я тоже писал.

Тот же хаскель у нас не прижился, хотя активно пробовали. Лиспом я по молодости увлекался, но не зашло. Я бы хотел что бы плюсы были заменены каким нить D/растом/…, но я до этого наверное уже не доживу, несмотря на бурное развитие ИТ. Монополии бывают очень устойчивы.

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

Хм-м-м, если я правильно понял, о чем ты, то тогда мой вариант будет «три-четыре».

Место на хэндл я не учитываю.

Рассмотрим shared_ptr. Тогда доп. блоки это: control block, shared_ptr storage [string], string storage [char…].

Теперь рассмотрим строку, в которую встроен счетчик ссылок. Строка мутабельна, поэтому будет перемещаться в памяти, с каждым перемещением указатели на нее будут протухать. Поэтому нужно выделять отдельно control block и string storage [char…], и отдавать указатели именно на control block, который в памяти перемещаться не будет.

Все это можно решать CoW-строками, но shared_ptr это НЕ CoW-строка. CoW-строкой какое-то время был std::string – но это порождало довольно неочевидные выстрелы в ногу.

очень странные люди, потому что иногда они ради 3% производительности накладывают вето на интроспекцию

Это не единственная проблема с интроспекцией в предложенном виде.

Хотя на самом деле нифига не являются, они намного медленнее интрузивных

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

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

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

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

Ну как сказать: санитайзеры являются очень хорошим подспорьем в этом деле.

Ну, и какие еще есть функции у union, которых нет у каста указателя?

strict aliasing и удобство использования.

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

а более адекватные люди

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

которые не только смотрят на внешний узор, а еще и читают сам код.

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

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

Вы не спорите. Вы изливаете собственную боль. От незнания и непонимания инструмента.

Грепание по сорцам Cfront 1.0 подтверждает мою идею — почти все использования const являются типом const char *, то есть, указатель на строковую константу.

Во-первых, const был добавлен в язык только в 1989-ом, т.е. сильно позже появления Cfront 1.0.

Во-вторых, мы обсуждаем тот const, который есть сейчас.

А если еще вспомнить, что стандарты часто пишутся кретинами

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

Ну как ты сделаешь иначе список const char *?

На самом примитивном уровне:

struct list_node {
  const char * m_payload;
  list_node * m_prev;
  list_node * m_next;
};

И в чем проблема?

Список и его значение имеют абсолютно разные типы и к ним могут предъявляться разные требования — не нужно шланговать.

Вы бы это… Хоть раз что-то конкретное сказали. А то пока какие-то воздушные замки и выдуманные проблемы.

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

Ололошеньки, подводные камни на самом берегу: а что, если кто-то поменяет возвращаемое по ссылке non-const значение? У нас же const Container &?

Кто, что и как поменяет? Давайте уже перейдем к конкретным примерам кода.

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

Жму руку, только это значит «перестать лепить сложные превращения const ссылок»

Во-первых, не значит.

Во-вторых, что это за цитата «перестать лепить сложные превращения const ссылок» и к чему она здесь?

Не только лишь все понимают, что нечитаемые библиотеки, подобные STL, очень трудозатратны при поддержке

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

Я не намерен её тут вытягивать: свое мнение я высказал, а претензий по существу не вижу.

Т.е. вы сказали откровенную чуйню, а то, что это именно что чуйня, вас не волнует?

Прелесно.

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

Это потом уже за уши притянута массивоподобная семантика.

Это не за уши притянутая семантика. Это основная цель vector-а.

Да-да, внутри std::vector тоже есть ссылка на массив

Потроха реализации vector-а к семантике, с которой имеет дело пользователь vector-а, не имеет отношения.

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

Вы не спорите. Вы изливаете собственную боль. От незнания и непонимания инструмента

Не могу не процитировать:

Мы вовсе не врачи — мы боль (с) А.И.Герцен

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

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

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

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

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

Уже срач на десятки страниц, а всё элементарные вещи понять не можете. Между const и constexpr почти ничего общего.

Какое-то воинствующее невежество.

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

Я когда то пытался сделать универсальную генерилку плюсового кода на питоне, не вышло по ряду причин.

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

Мне вообще больше физика интересна, но приходится программировать…:-(

AntonI ★★ ()

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

class Base { 
public:
   int _base = 100;
};

typedef const Base ConstBase;

class CDerived: public ConstBase {
public:
   int _derived = 200;
};

void ffun(){
   ConstBase lcb;
   lcb._base = 100; ///тут ошибка ибо класс констатный 

   CDerived lcd; 
   lcd._base = 100; /// a тут ошибки нет, хотя поле констатного класса.
}

гы.

alysnix ()
Закрыто добавление комментариев для недавно зарегистрированных пользователей (со score < 50)