LINUX.ORG.RU

юнионы в C++

 


2

4

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

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

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

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

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

★★★★★

Последнее исправление: xaizek (всего исправлений: 4)
Ответ на: комментарий от den73
  • вот берём первое, что попалось - libsdl2 - и там есть union.
  1. SDL2 – это сишная библиотека.
  2. Использование union в SDL2 полностью целесообразно.

Да, можно переписать на variant. Нет, никакого смысла нет. Никто не пишет по 15 event loop’ов в день, чтобы иметь возможность в них ошибаться.

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

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

Какие, например?

А так - я не знаю и не говорю.

Ты уже 3 страницы не знаешь, но очень много говоришь.

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

Можно придумать защиту от дурака, но только от неизобретательного (с)

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

Почему ты считаешь, что вычисление слева направо или справа налево естественно, когда наиболее естественным является вычисление в том порядке, который установлен calling convention?

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

Принимается, спасибо.

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

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

Ещё это может использоваться при работе с бинарными форматами и протоколами где данные хитро побитово упакованы.

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

Ещё до С++11 делали либо свои умные указатели, либо из библиотек использовали (того же boost).
Из библиотек, те же Boost, Qt, Poco

Меня забавляет тот факт, что среди крестовых разработчиков манагер памяти считается чем-то незыблемым и данным свыше. Если у тебя требования к нестандартной работе с памятью (а это многие низкоуровневые системные штуки и в том числе ядро) — добро пожаловать в ад. В частности, потому линь не пишут на крестах. То есть, очевиден уклон C++ в строну несистемного программирования — сам Страуструп писал в мемуарох о том, что Си с классами разрабатывался именно для упрощения писания сложной прикладнухи, и, по моим впечатлениям, в крестах ничтожные преимущества при писании низкоуровневой системщины/драйверов.

Кстати, что-то похожее я не так давно писал про Rust — он каким-то образом сумел воспроизвести многие преимущества и недостатки C++.

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

Я забуду, это будет не скоро. Но анонсы можно будет прочитать в телеге: https://t.me/JAOS_OS_na_russkom_jazyke

ТЫ на крестах собрался писать ОС или обвязку? В низкоуровневой системщине преимущества крестов настолько ничтожны, что можно заморочиться, а можно обойтись и без крестов. Если речь идет про более высокоуровневые утилиты, то я бы посоветовал обратить взор на Go. Слишком уж C++ убог и низкоуровнев.

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

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

Меня забавляет тот факт, что среди крестовых разработчиков манагер памяти считается чем-то незыблемым и данным свыше.

А это точно так?

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

Проекты, которые на С++ писать нужно, будут содержать практически исключительно скрипты сборки, а не декларативщину.

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

  • Часть кода в скриптах сборки занимается поиском установленных хедеров и либ в сборочном окружении. Например find_package в симейке, который может подтягивать монструозный модуль типа такого. Пакетный менеджер делает этот императивный понос полностью ненужным. Достаточно декларативно описать зависимости в манифесте без всякого скриптования, а пакетный менеджер автоматически выкачает, скомпилит и подключит нужные библиотеки.
  • В скриптах сборки часто используются различные препроцессоры и кодогенераторы типа doxygen, moc и т.д. Их можно запилить в JSON манифесте через декларативные правила сборки аля make. Да-да, make декларативен, а не императивен.
  • Еще часто используются различные кастомные опции сборки типа BUILD_EXAMPLES=ON. С этим уже посложнее, но в принципе это можно сделать через if-выражения, которые включают/отключают нужные секции декларативного манифеста. Пример из хаскельного cabal-файла: тыц.
  • И только если позарез нужна императивщина и одним декларативным манифестом ну никак нельзя обойтись, вот только тогда имеет смысл писать скрипты сборки в виде исключения. Причем не на процедурном CMake, а на самом С++.

Ради интереса прошелся по 10 Most Downloaded крейтам на crates.io: build.rs нашелся только в 4 из них. Ну то есть раст во многих случаях может успешно обходиться без всяких скриптов сборки. Что мешает то же самое сделать в С++?

Проблемы лаб, которые зачем-то пишутся на С++ вместо условного питона, меня волнуют мало.

Хорошая иллюстрация, почему каждый условный питон имеет свой условный PyPI и pip, а крестоилитка в 2к22 так и продолжает надрачивать на генереные портянки баша из автотулзов. И ничего лучшего видимо уже не предвидится.

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

Но зато одну хорошую ошибку (закладку) в цикле обработки сообщений можно растиражировать во много мест. И при том наличие плюсовой обёртки от этого вряд ли защитит. Это относится к вопросу нашей темы, я так думаю, тем, что если мы программируем на плюсах, а система на сях, то безопасность и надёжность такой системы получается по слабому звену. А при том линкус вроде как весь на сях написан. Т.е. С++ в этом направлении не помогает.

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

В частности, потому линь не пишут на крестах.

Имхо это скорее по причине косности, инерции и личной ненависти Торвальдса к С++. Гугл вот так не считает и пишет ядро Zircon на подмножестве C++17, правда изрядно урезанным и без STL в кернелспейсе.

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

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

Но зато одну хорошую ошибку (закладку) в цикле обработки сообщений можно растиражировать во много мест

Какое отношение намеренное создание закладок имеет к ЯП?

Ошибка в SDL2 не является сколь-нибудь критичной для системы, это библиотека для разработки мультимедиа, обычно игр.

Это относится к вопросу нашей темы

…примерно никак.

А при том линкус вроде как весь на сях написан. Т.е. С++ в этом направлении не помогает.

Шизофазия. От union’ов в SDL2 к линуксу и прикладному коду. Так и напишете в своей телеге: С++ плохо, потому что в SDL2 union’ы наружу торчат?

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

Я бы сказал, что старый С++98 вполне себе метил в ту же нишу, что и С.

С точностью до наоборот. С++98 косил в джаву, а джава косила в С++.

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

С точностью до наоборот. Перечислять, какие же возможности, добавляемые в С++14,17,20,23 залезают в «высокоуровневую прикладнуху», конечно же, никто не будет.

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

Пиши свои проекты на чём хочешь, оберон там, яр - не важно. Это и будет лучшим доказательством практичности этих языков. А сейчас выглядит как попытка оправдания - «да, на си++ можно написать операционку. Да, это был бы практичный выбор. Да, я не знаю си++ и поэтому пытаюсь оправдать его неиспользование мнимыми (а пусть даже и реальными) недостатками…» Сюда хорошо ложатся слова Нистрема из craftinginterpreter: «Я не думаю, что книги по орнитологии беспокоятся об оправдании их существования. Они предполагают, что читатель любит птиц, и начинают учить.»

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

Скрипты сборки - это крайне однотипные и шаблонные задачи, делающие примерно одно и то же

То же самое можно сказать про декларативщину.

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

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

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

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

В скриптах сборки часто используются различные препроцессоры и кодогенераторы типа doxygen, moc и т.д. Их можно запилить в JSON манифесте через декларативные правила сборки аля make. Да-да, make декларативен, а не императивен.

make декларативен ровно на уровне таргетов, да и то условно. Дальше императивщина во все поля.

Еще часто используются различные кастомные опции сборки типа BUILD_EXAMPLES=ON. С этим уже посложнее, но в принципе это можно сделать через if-выражения, которые включают/отключают нужные секции декларативного манифеста.

Желаю почаще писать императивные секции декларативных манифестов. Желательно на XML.

Пример из хаскельного cabal-файла: тыц.

Тот самый cabal, который давно сломан и не чинится. Какое отношение, кстати, Haskell имеет к системщине?

Ради интереса прошелся по 10 Most Downloaded крейтам на crates.io: build.rs нашелся только в 4 из них. Ну то есть раст во многих случаях может успешно обходиться без всяких скриптов сборки. Что мешает то же самое сделать в С++?

«Most Downloaded» они потому что они – клей, которому ничего более не нужно, с системой они взаимодействуют никак – или делегируют своим зависимостям.


А теперь откровение: в С++ для ho-либ зачастую также не нужна система сборки. Почему-то адвокаты cargo.toml про это регулярно забывают.

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

Я пока просто пишу телегу про плюсы, не хочу ломать интригу

А я просто уже несколько подходов опросов лора делал по этому поводу, а с недавних пор и сам стал поф. кодить на крестах.

Меня забавляет тот факт, что среди крестовых разработчиков манагер памяти считается чем-то незыблемым и данным свыше.

А это точно так?

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

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

С++98 косил в джаву

А мужики-то и не знают. Не расскажешь, чем именно С++98 косил в джаву? Надеюсь не GC, интерфейсами и генериками?

Перечислять, какие же возможности, добавляемые в С++14,17,20,23 залезают в «высокоуровневую прикладнуху», конечно же, никто не будет.

У нас видимо какие-то разные представления о высокоуровневой прикладнухе. Полоумные указатели, лямбды, модули, рейнджи, корутины, std::filesystem, монадические интерфейсы для std::optional и т.д. - в какую нишу они залезают, если не в высокоуровневую прикладнуху? Двигать байтики в микроконтроллерах без ОС и файловой системы?

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

типовые сценарии сборки С++ несостоятельны без обращения к системе и действий, выполняемых сейчас в скриптах

Например какие такие «обращения к системе» нужны в типовых сценариях сборки, без которых они не состоятельны? И почему нельзя скажем для 90% типовых сценариев сборки предусмотреть декларативный манифест аля Cargo, а оставшиеся 10% специальных случаев так уж и быть, доделывать императивными скриптами, прописанными в декларативном манифесте?

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

Именно. В этом и проблема, что пакетных менеджеров существует целый зоопарк, они не включены в стандарт и каждый из них ущербен по своему, из-за чего три четверти крестовиков так и продолжают пихать зависимости себе в репу. CMake может в сборку, но не может в менеджмент пакетов. Conan наоборот чистый менеджер пакетов, не умеющий в сборку. Meson пытается делать и то, и то, но с таким количеством пакетов ему хотя бы до конана как до луны раком. Остальные поделия еще более маргинальны и малоизвестны. Разительное отличие от стандартизированного Cargo, которым собираются любые крейты в экосистеме раста.

Желаю почаще писать императивные секции декларативных манифестов. Желательно на XML.

Не самый плохой вариант кстати. На оффтопике так и делают испокон веков. Открыл проект в проприетарной студии, натыкал опций в гуйне с настройками проекта, добавил условные конструкции руками в XML-файл, ткнул Build, все собралось. ИЧСХ, это даже как-то работает. Любителям долбиться в императивные скрипты сборки стоит взять на заметку.

Тот самый cabal, который давно сломан и не чинится. Какое отношение, кстати, Haskell имеет к системщине?

Да, это тот самый Cabal, который к версии 3.0 научился в nix-style сборку, починил все проблемы с депенденси хеллом и теперь на световые годы впереди традиционных пакетников. Кабал файл тут просто для примера, как можно сделать if-конструкции в декларативном манифесте. Не все же XML или JSON руками править. Думается, что этот же самый подход прекрасно применим и к С++.

А теперь откровение: в С++ для ho-либ зачастую также не нужна система сборки. Почему-то адвокаты cargo.toml про это регулярно забывают.

С этим да, согласен, но думаю не надо тебе объяснять, что header only либы непрактичны в большинстве случаев. И вообще, я сварщик ненастоящий, на расте вообще не пишу ни разу, я больше топлю за декларативный подход к сборке, а Cargo это только пример, наиболее приближенный к реалиям С++.

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

Полоумные указатели

Высокоуровневость так и лезет.

лямбды, модули

Никакого отношения к «уровню» языка не имеют.

рейнджи

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

корутины

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

std::filesystem

Единственный более-менее валидный аргумент

монадические интерфейсы для std::optional

в какую нишу они залезают, если не в высокоуровневую прикладнуху?

Ни в какую. Кроме filesystem это чисто внутриязыковый клей для удобства написания кода, прозрачно компилируемый в машинный код и обычно зерокост. От того, что байты двигаются в ranges::copy вместо memcpy, язык высокоуровневым или низкоуровневым не становится.

Не расскажешь, чем именно С++98 косил в джаву? Надеюсь не GC, интерфейсами и генериками?

Кроме генериков все в цель. Ну и «поддержку GC» завезли лишь в С++11, не в С++98.

Siborgium ★★★★★
()
Последнее исправление: Siborgium (всего исправлений: 1)

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

юнион же подобные размещения позволяет делать вполне безопасно.

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

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

Наоборот везде в стандартной библиотеке можно указать кастомный аллокатор, можно переоределить operator new и т.д..

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

ТЫ на крестах собрался писать ОС или обвязку? В низкоуровневой системщине преимущества крестов настолько ничтожны, что можно заморочиться, а можно обойтись и без крестов.

Преимущества C++ в ядре огромны в виде RAII, std::unique_ptr, классов с виртуальными методами, классов-контейнеров, кода, выполняемого во время компиляции.

Я причастен к разработке ядра ОС на C++ (Haiku).

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

Например какие такие «обращения к системе» нужны в типовых сценариях сборки, без которых они не состоятельны?

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

И почему нельзя скажем для 90% типовых сценариев сборки предусмотреть декларативный манифест аля Cargo, а оставшиеся 10% специальных случаев так уж и быть, доделывать императивными скриптами, прописанными в декларативном манифесте?

Я уже послал смотреть сборку Chromium и других известных проектов на С++. Пропорции ровно обратные: 90% нетиповых сценариев и 10% типовых.

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

Это не проблема, а жирный плюс.

CMake может в сборку, но не может в менеджмент пакетов.

Нет, может, хотя это не его прямое предназначение. См. ExternalProject_Add и FetchContent.

Conan наоборот чистый менеджер пакетов, не умеющий в сборку.

Conan интегрируется с CMake и meson и отлично работает с ними. Зачем создавать что-то еще – неясно.

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

Meson является менеджером пакетов в той же степени, что и CMake – постольку, поскольку. В первую очередь это система сборки.

Не самый плохой вариант кстати. На оффтопике так и делают испокон веков

добавил условные конструкции руками в XML-файл

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

Разительное отличие от стандартизированного Cargo, которым собираются любые крейты в экосистеме раста.

Никого не волнует, что и чем собирается, тем более в экосистеме раста.

из-за чего три четверти крестовиков так и продолжают пихать зависимости себе в репу

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

С этим да, согласен, но думаю не надо тебе объяснять, что header only либы непрактичны в большинстве случаев

Нет, ho либы практичны в большинстве случаев.


Есть и другой важный момент: для типовых сценариев CMake/meson ничем не хуже Cargo. Добавить зависимость в проект – вопрос 1-2 строк, при этом возможность писать все те же императивные скрипты никуда не пропадает.

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

Ошибка в SDL2 не является сколь-нибудь критичной для системы, это библиотека для разработки мультимедиа, обычно игр

А также некоторых эмуляторов, например, QEMU.

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

Какое отношение намеренное создание закладок имеет к ЯП?

Может быть имеет, а может быть и не имеет. Какое твоё мнение:

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

В зависимости от твоего ответа попробую ответить дальше.

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

Вот похоже на правду. Мне изначально казалось, что в случае линукса из-за сишного ядра и API язык С++ не сильно поможет, а вот если ОС разрабатывается с нуля без оглядки на POSIX, то C++ может дать преимущества. Другое дело, были какие-то вопросы с ООП - API, но тут я просто не в курсе. И у C++ есть свои минусы.

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

Наоборот везде в стандартной библиотеке можно указать кастомный аллокатор, можно переоределить operator new и т.д

Теоретически возможно != удобно и надежно. Когда ты пишешь прямую работу с памятью, а кресты тебе внезапно начинают копировать объекты и выделять под них память, то хочется выкинуть кресты на помойку и снова писать на Си... или хотя бы на расте, где в фундаменте лежит семантика перемещения, а не копирования как в крестах. А если ты выкинешь из крестов неявное поведение в виде всех копирующих конструкторов/операторов присвоения и ИСКЛЮЧЕНИЯ — что останется от библиотек? Я подчеркиваю, что исключения являются важным источником скрытой работы с памятью (в деструкторах), которую очень тяжело отлаживать в нетривиальных случаях со взаимозависимостями меж уничтожаемыми объектами, и во многих случаях после одного исключения приложение просто валится — либо знаменитый парад окошечек, либо знаменитый abort из-за исключения в обработчике исключения.

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

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

В новых версиях C++ эти проблемы во многом исправлены. Введены move semantics, emplace и т.д.. Можно запретить copy constuctor чтобы избежать случайного копирования.

Короче главная проблема C++ в том что программисты его не знают, а мнение имеют.

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

Ну вот то, о чём я даже почти не говорил - проблема в том, что программисты его не знают. А не знают, потому что он сложен и довольно быстро меняется. Это как раз главная проблема C++. Остальные проблемы менее важны, но тема именно про них.

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

Какое твоё мнение:

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

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

Я причастен к разработке ядра ОС на C++ (Haiku)

Спасибо, ты у меня уже записан.

Преимущества C++ в ядре огромны в виде RAII, std::unique_ptr, классов с виртуальными методами, классов-контейнеров, кода, выполняемого во время компиляции

Давай разберем сказанное по частям.

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

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

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

классов-контейнеров

В большинстве случаев эти контейнеры для конкретных типов можно просто взять и написать на Си. Да, потратишь больше времени, но это не какая-то пропасть. К тому же, напоминаю, что контейнеры STL далеко не бесплатны, они применяют мелкие вспомогательные структуры, которые заметно уступают интрузивным контейнерам (Boost.Intrusive, да).

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

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

В новых версиях C++ эти проблемы во многом исправлены. Введены move semantics, emplace и т.д.. Можно запретить copy constuctor чтобы избежать случайного копирования.
Короче главная проблема C++ в том что программисты его не знают, а мнение имеют

Деструкторы тоже можно запретить?

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

Гугл вот так не считает и пишет ядро Zircon на подмножестве C++17, правда изрядно урезанным и без STL в кернелспейсе.
https://fuchsia.dev/fuchsia-src/development/languages/c-cpp/cxx

Not allowed:
* Exceptions
* Operator overloading
* Virtual inheritance
...

В принципе, с подходом я солидарен. Правда, если ты прикинешь, что остается в сухом остатке, то выясняется, что это почти Си, только с шаблонами вместо макросов и с генерацией константных данных (в том числе vtable) во время компиляции.

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

RAII + unique_ptr убого по сравнению с defer-подобными финализациями

defer надо вручную писать при каждом использовании что не далеко ушло от ручного управления памяти и создаёт высокий риск ошибки во время написания программы. В случае std::unique_ptr удаление привязано к самому указателю и никаких defer писать не надо. Если очень надо чтобы объект не удалился, есть unique_ptr::release. В том числе этот метод позволяет передать указатель в легаси код не использующий std::unique_ptr.

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

Если так часто приходится делать, то скорее всего программист делает что-то не так. Такие случаи очень редкие и std::unique_ptr позволяет их обработать (тот же release).

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

В Haiku принято ошибки конструктора возвращать в пиле статус кода методом InitCheck. И вообще делать сложные вещи в конструкторе – плохая практика. Лучше слелать пустой объект, а потом его инициализировать обычными методами. И с наследованим проблем меньше станет.

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

Только через лютые костыли с препроцессором. И разумеется никакой типобезопасности.

К тому же, напоминаю, что контейнеры STL далеко не бесплатны, они применяют мелкие вспомогательные структуры, которые заметно уступают интрузивным контейнерам (Boost.Intrusive, да).

Речь не только про контейнеры STL. В Haiku например есть свои классы контейнеров интрузивных списков, интрузивных AVL деревьев, массивов на стеке и прочего. На Си это нельзя сделать без препроцессорных костылей и/или дублирования кода.

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

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

Это создаёт значительное преимущество в виде сокращения вероятности ошибок в коде и повышении понятности/поддерживаемости кода. Например для меня и некоторых других разработчиков Haiku код Линукса с glib/gtk нечитабелен и по возможности ориентируются на код *BSD. Никто так и не смог написать Haiku бекенд к GTK потому что стиль кода совершенно чужд и непонятен разработчикам и в итоге оказалось сделать проще слой совместимости с xlib на C++ (Xlibe, обсуждение с фанатами Линукса).

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

Я пока просто пишу телегу про плюсы

Не понял что именно ты пишешь. Но если это телега в негативном смысле, то она уже есть, и на мой взгляд достаточно адекватная: гуглить «The Dark Side of C++». Для Ъ: https://www.scribd.com/document/17341098/The-Dark-Side-of-C

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

Мне, честно сказать лень, потому что это настолько очевидно, что я просто не пойму, где у тебя проблема с признанием этого простого факта. Но попробую ещё раз. Перед тобой стоит задача спрятать закладку в коде. ТЗ на функционал программы определено и твою закладку будут искать специалисты. Но реализовать закладку ты можешь произвольно. Также ты можешь писать программу на любом из 4 языков: ассемблер, яву, Си или Си++ Предположим, ты хорошо знаешь все 4 языка. Какой из языков ты выберешь?

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

Перед тобой стоит задача спрятать закладку в коде

Уже всё спрятали до нас: (файл, который нужно закоммитить перед уходом с работы) https://habr.com/ru/post/197266/

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

От такого у меня есть антидот - vs code + bear. Хотя, конечно, не всегда он сработает, а лишь сократит время выявления такой гадости.

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

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

  • нужно таки освоить язык;

  • вытащить руки из жопы;

  • включить голову.

eao197 ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.