Комментарии 125
Всё это напоминает политику, а не полезное движение в сторону развития. В язык набежали нежные смузихлёбы, которым сложнааа кодить безопасно/эффективно, и начались попытки принести в долгоживущую систему куски раста, го, и прочих короткоживущих хипстерских поделий. Мы все помним, на какой волне был Руби в свое время - и где он сейчас?C++ и так перегружен, и вносить туда всякие сомнительные вещи недопустимо, на текущем этапе здоровый консерватизм наиболее выгодная стратегия развития. Хотите смузячно-хипстерских фич - форкайтесь и пилите свой лунапарк, либо возьмите го/раст...
Невозможно сделать безопасный и эффективный ЯП одновременно. За дефолтную безопасность и защиту от дурака надо дорого платить производительностью. Это фундаментальный закон мироздания, иначе не может быть. Возможность отстрелить себе ногу в C++ это не баг, а фича.
То, что за дефолтную безопасность надо дорого платить -- самая странная иллюзия людей, которая бы прошла, если бы они хоть чуть интересовались другими языками.
Есть два варианта платы: плата временем выполнения в рантайме и плата временем на ублажение компилятора.
А Вы пробовали скомпилировать на этом "другом языке" кодовую базу схожую по объему с энтерпрайз проектами, написанными на C++? Пару итераций и рабочий день закончен.
И когда Microsoft/Google рапортуют о лучшей производительности разработчиков на "другом языке", мне это видится как "мы ещё не написали на другом языке достаточно кода, чтобы ощутить на себе всю тяжесть защиты от дурака".
.NET (C#) и Java считаются? Видел огромные монолитные проекты из сотен достаточно крупных модулей, холодная компиляция с нуля занимала минут 5-15, но последующие сборки при частичном изменении проекта - от единиц от десятков секунд. Думаю, с такой скоростью сборки можно сделать за день чуть больше пары итераций. Возможно вам не повезло, и вы видели огромные проекты на "других языках", авторы которых просто не смогли правильно настроить инкрементальную сборку?
Ага, на Java проект больше C++. На сях 30 минут собирается, на java 5
Java и C# платят рантаймом. "Другой язык" в моем комментарии - это Rust
В плюсах во время компиляции можно на шаблонах алгоритм произвольной сложности выполнять, тащемта.
Поддерживаю. К тому же, многие проверки можно делать на этапе компиляции.
Если считать, что люди никогда не делают ошибки, что не существует непостоянных багов.
Тут возможно не просто выстрелить себе у ногу, а выстрелить себе в ногу тогда, когда этого ожидаешь меньше всего. Шутливый "Закон" Мёрфи.
Если кому-то нравится копаться в low level г****, то это его право.
Помимо этого есть более важные вещи, как архитектура софта вообще, эффективная утилизация ресурсов вообще. Если говорить про ОС общего назначения... То тут не редко пишут софт в один поток (речь о синхронных вызовах), забывая, что файловая операция это латентная операция с ФС, диском ... и никакие передовые SSD не помогут и не у каждого оно есть. Конечно это не всегда нужно. Например не обязательно для каких-то CLI программ, то там юзер может и подождать. А вот для сервисных программ, которые обслуживают события - это очень даже может быть плохо.
расскажите молодому начинающему, что случилось с Ruby в свое время
здоровый консерватизм наиболее выгодная стратегия развития.
тогда почему консерватизм заключается фразой "ничего не трогаем и тогда ничего не сломается", а все проблемы решить проблемы превращаются в помесь басни "лебедь рак и щука" и ведра крабов.
Вот не люблю Го, но давайте придерживаться фактов: этому языку уже 15 лет, то есть это примерно как плюсы в 2000 году. Хотя да, тогда плюсы именно и называли короткоживущей поделкой для тех, кто не смог в сишечку.
Хотя да, тогда плюсы именно и называли короткоживущей поделкой для тех, кто не смог в сишечку.
Гм-гм, как можно смочь в плюсы, но не смочь в сишечку? Вот обратные примеры есть даже в местных каментах, а о том, о чем вы говорите, я как-то даже не слышал.
Ну в плюсах есть RAII, умные указатели, this
в методы как-то сам передается, ещё какой-то там синтаксический сахар, система типов пытается что-то там из себя изобразить... Пример того, что я имею в виду – Линус про C++ и программистов на нем (хотя конкретно этот письмо было и позже 2000, да).
Я согласен с тем, что C++ примерно в бесконечное число раз сложнее С, но это предмет для отдельного сра... обсуждение.
Хотя да, тогда плюсы именно и называли короткоживущей поделкой для тех, кто не смог в сишечку.
Пример того, что я имею в виду – Линус про C++ и программистов на нем (хотя конкретно этот письмо было и позже 2000, да).
Линус о другом писал - C++ даёт штуки (STL, Boost, исключения), которые обязательно потянут в ядро. С чего вдруг их потянут в ядро, почему? Потому в этом случае плюсовикам можно показать средний палец и грязно выругаться. Это хорошо, а если серьёзно? Да не нравится ему C++ и всё тут. В дискуссии этого года в рассылке прозвучало очевидное:
Note that no one in their sane mind would expect to use all the features of C++. Just like we have "kernel C" (currently a subset of C11 with a relatively large set of allowed compiler-specific extensions) we would have "kernel C++"
Мне кажется, это все из одной оперы: "придумали себе STL какой-то, вместо того чтобы void*
кастовать, как отцы завещали!"
C++ даёт штуки (STL, Boost, исключения), которые обязательно потянут в ядро
В виндовое ядро C++ потянули почти тридцать лет назад, но ни STL, ни Boost, ни исключений там, слава богу, нет. Выходит, могут, когда захотят.
А как-же structural exceptions?
В виндовом ядре есть C++? Я его близко не видел, но что-то думал, что там только голый C, только хардкор.
Само ядро действительно написано на голом C. Также на C традиционно писались драйверы устройств.
Но ядерная модель потокового звука/видео (Kernel Streaming) изначально делалась с заточкой на COM, поэтому все драйверы и системные модули их подержки (ks и portcls) сразу были написаны на C++.
С тех пор и традиционные драйверы устройств некоторые стали писать на C++.
Я писал на C++ еще 32-разрядные драйверы VxD для Win9x в конце 90-х, когда поддержки этого в DDK не было вообще, и приходилось делать собственную обертку, и был в этом отнюдь не первым. :)
А на какой волне был Руби? Ценность Руби разве не в Rails? Медленный интерпретатор, monkey-patching, в языке вообще есть что-то ценное?
По тексту есть номера сносок, но текста сносок нет в статье
Del
По-моему, у огромного числа людей существует фатальное заблуждение: им внушили, и они теперь считают за норму ситуацию, и считают, что это вполне неплохо и даже хорошо, если стандарт (какой бы то ни было — хоть на ЯП, хоть на резьбу болтов) меняют каждые пару лет. В идеале, стандарт вообще не должен меняться. В реальном мире (сейчас набегут сторонники «реального мира») было бы терпимо, если бы по исключительным поводам и основаниям стандарт допускалось пересматривать и менять раз в лет 10—15.
Стандарт, в котором уже десять лет закралась и сидит не-фатальная ошибка, лучше, чем «идеальный» стандарт, который меняют каждый день — такова моя система ценностей. Поэтому мне больно читать про всё то, что делается с С++ в последние годы.
А USB какого стандарта вы используете?
Вот версии USB как раз и выходят раз в 10 лет, с ним все нормально. Хотя в последний, конечно, напихали слишком много всего.
А USB какого стандарта вы используете?
2.0
Возможно, это просто травматический опыт (я пытался выучить плюсы как второй язык в пару к чистому С и толком не смог), но, имхо, изменение стандарта это нормально, если время от времени сбрасывать обратную совместимость. При разработке "Цивилизации" был хороший принцип: в новой игре треть старого, треть нового, треть измененного, и поэтому поиграв в 2 цивилизацию, можно легко вникнуть в 3 и чуть сложнее в 4 (если пропустил 3). Попытки тащить огромный груз совместимости приводят к тому, что кажется, будто при программировании на С++ пытаешь играть сразу во все игры серии с непонятным переплетением механик.
В Питоне вон эту совместимость так сломали, что потом 15 лет расхлебывали. И вроде только-только расхлебали, во всяком случае я уже избавился наконец от второго питона и не попадаю в ситуации, когда половина нужного софта и библиотек написаны под второй, а половина под третий.
Думаю, многие на это посмотрели и решили, что так не хотят.
Ты действительно ожидаешь адекватности от этих людей? Есть такой принцип, согласно которому, зная 20% функционала, можно получить 80% результата, и он ни смотря ни на что - работает. Этот принцип не говорит ни в коем случае о том, что нужно остановиться в развитии или не изучать более полно нужный тебе инструмент, но я более чем уверен, что подавляющая часть комментаторов ниже и выше, этих замечательных людей из секты свидетелей раста и ему подобных, используют 80% функционала, для того чтобы получить 20% результата. Других разумных объяснений их поведению и мышлению нет. Просто очень странно, что чуваки, которые пишут 0.01% всего кода в мире, постоянно пытаются диктовать, как и каким образом писать оставшиеся 99.99% кода всем остальным программистам, которых всё устраивает.
Так стандарт и не меняется. С'99 остаётся до сих пор C'99. C++14 стался C++14 даже после выхода C++17. Они не меняют стандарт языка, а выпускают новый стандарт. Это другое.
Они не меняют стандарт языка, а выпускают новый стандарт.
Если буквоедствовать, то можно возразить, что магазин стандартов ISO старые версии изымает из продажи и помечает их как "отозванные". На что можно возразить - а магазин стандартов IEC - как "пересмотренные" и продолжает продавать. Затем можно возразить им всем: ребята, ну кто покупает WinRAR стандарт, пользуйтесь черновиками. И не испытывайте лишнего пиетета перед стандартом, вон, Linux активно использует расширения GCC и Линус ценности в стандарте не находит, на C++ зачастую тоже пишут под GCC/Clang: "V8 officially dropped support for MSVC" (тыц), "Firefox 63 onward MSVC is not supported" (тыц).
Если буквоедствовать... Тогда претензия не к тому, что издают новый стандарт, а что отзывают старый. Почему отзывают? Потому что он не удовлетворяет современным требованиям. Что делать, чтобы не отзывать? Вместо выпуска нового, надо изменить старый стандарт! И вот в этом случае мы просто берём и копи-пастим изначальную претензию, которая уже без придирок будет соответствовать ситуации.
Александреску когда-то пилил D, но чёт не слышно про него ничего...
Он, к сожалению, умер под эффектом второй системы
Последняя крупная новость была в январе, об ответвлении под названием "язык OpenD". Если про D вспоминать в контексте статьи, то у него есть @safe
-атрибут (который, как пишут, на main() охватывает программу целиком), но unsafe-by-default для CISA недостаточно, судя по их таблице: "Memory-unsafe: Assembly, C, C++, C/C++ Header, Cython, D".
----
Создатель D отметился на HN (WalterBright) в обсуждении этой статьи.
Не сказать прям, что умер, но не хайпе уж точно.
Так-то замечательный язык, возможно лучшее из т.н. C-подобных языков. Много очень классных вещей и документация отличная, не говоря о времени компиляции. Помимо компилятора (dmd) есть ещё режим интерпретатора (rdmd). B режим betterC впридачу.
Сообщество довольно активное на самом деле.
Активно программирую на D много лет. Жив он.
Но почему-то компании его использование не афишируют - будто стесняются
У меня сложилось впечатление, что первый D был вполне неплохим языком, но местами со странными вещами (например x.atomicOp"+="(1)
).
Так и не выпустив его в полноценное плавание, Александреску взялся делать вторую версию (улучшенную и исправленную), которая сама уже не выстрелила особо (в смысле не стала сколько-нибудь популярным языком) и утащила за собой первую версию (давайте подождём второй, улучшенной и исправленной), потеряв время.
А жаль. Очень жаль. Искренне жаль.
Предлагаю переименовать С++ из языка в семейство языков. Такова ведь судьба всех выживших языков древности: нет давно языка LISP, а есть семейство LISP-подобных языков, новые диалекты COBOL не полностью совместимы между собой, и т.д. Вот и давайте решим, что, например, С++11 это один язык, а будущий С++25 - другой. Кому важнее безопасность - пусть делает porting со старого языка на новый, кому не так важна - пусть так и объявит, у нас язык С++11 и живите с этим. И в вакансиях на работу, и в резюме так и указывать.
Это решит очень много споров.
А мне это и нравится в C++: свобода. Когда надо, можешь использовать все плюшки, типа смарт-поинтеров, функциональщины, контейнеров, а надо - спустился до указателей, буферов, до asm. Не нравятся стандартные строки - написал свои. Понадобился свой аллокатор - нет проблем.
А безопасность? Ну, C++ даёт большую силу, а "с большой силой приходит и большая ответственность". И я боюсь, что в погоней за "безопасностью" заберут эту свободу, и просто выкинут всё, что хоть как-то позволяет выстрелить в ногу, и язык превратится в какую-то манную кашку.
"О, смотрите, ножом можно порезаться, давайте отберем ножи. А хлеб пусть нарезанный покупают". Как бы такой подход не довел до всеобщей кастрации, "а то вы же изнасиловать кого-нибудь можете".
Самое смешное, что наличие низкоуровневых элементов практически никак не мешает добавлению средств увеличения безопасности.
Достаточно внести в компилятор простую и дешевую доработку - и вот он уже автоматически генерирует проверку каждого указателя при каждом его разыменовании. Да, это сразу увеличивает затраты на выполнение, но еще одна простая и дешевая доработка - и эти проверки [не] генерируются для явно указанных фрагментов, или по указанному условию.
Еще одна простая/дешевая доработка - и на каждое использование объекта (перед и/или после использования) компилятор генерирует вызов указанного метода, который проверяет целостность объекта.
Таких несложных доработок можно сделать довольно много, потом оценить, какие из них больше способствуют повышению безопасности, и предложить в Стандарт.
Но разработчики компиляторов предпочитают десятки лет тянуть убогие огрызки подобных средств (каждый свои), и никакой унификацией даже близко не пахнет.
Есть риск получить вместо плюсов Java или Python :) Было неявное соглашение для С и С++: программист знает, что он делает. С одной стороны, должен избегать UB, а с другой - если использует UB или implementation defined фичи языка, то он это делает специально, зная, что получится. К сожалению, это соглашение давно нарушается: компиляторы предполагают полное отсутствие UB в коде для агрессивных оптимизаций. Таким образом, ваше предложение нарушает оба основных тренда: "скорость превыше всего" и "я знаю, что я делаю". Ну и до кучи старый принцип "не плачу за то, чем не пользуюсь",
Есть риск получить вместо плюсов Java или Python :)
Это как? :) Я пока не предложил никаких функциональных расширений - только автопроверки для повышения безопасности применения существующих. У меня, конечно, есть идеи и по функционалу, но кому они нынче интересны? :)
если использует UB или implementation defined фичи языка, то он это делает специально, зная, что получится.
Так и пусть использует. Если ему действительно нужно разыменовать невалидный указатель - укажет это явно (какими-нибудь прагмами, например), и именно в этом месте автопроверка вставлена не будет.
"скорость превыше всего"
Кому нужна скорость, тот не будет этого использовать - по крайней мере, там, где скорость реально нужна.
"я знаю, что я делаю"
Вот пусть и заявит об этом явно. :) Чтоб в случае обоснованных сомнений можно было включить автопроверки и потыкать его носом в их результаты. :)
В идеале, конечно, такие автопроверки должны навешиваться по умолчанию, и требовать явного отключения, поскольку на C++ уже давно пишет куда больше тех, кто лишь думает, будто знает, а на деле знает недостаточно. Уверен, что знаешь - поставил хорошо видимые в тексте маркеры.
"не плачу за то, чем не пользуюсь"
Здесь ничего не меняется. Если от автопроверок есть выгода в плане раннего обнаружения ошибок - значит, ими пользуются. А если они не способны дать выгоду, их и включать не нужно (но лучше таки отключить включенные по умолчанию).
Я пока не предложил никаких функциональных расширений - только автопроверки для повышения безопасности применения существующих.
"не плачу за то, чем не пользуюсь". Если разработчик пишет for (size_t i=0; i < N; i++) - да на здоровье. Итератор с проверкой границ пишется очень просто, но если его нет - предполагается, что он не нужен.
В идеале, конечно, такие автопроверки должны навешиваться по умолчанию, и требовать явного отключения, поскольку на C++ уже давно пишет куда больше тех, кто лишь думает, будто знает, а на деле знает недостаточно. Уверен, что знаешь - поставил хорошо видимые в тексте маркеры.
Вот про это я и говорю "я знаю, что я делаю". А вы неявно предполагаете, что разработчик не знает. В такой химере, как плюсы, это может, и правда, но противоречит идеологии С++. Да, людям (бизнесу) обычно не нужны ни скорость исполнения, ни экономия ресурсов, ни надежность с безопасностью, но такие вещи коренными изменениями имеющегося языка решать не стоит. Хочешь загнать разраба в узкий коридорчик - ну вот тебе Го, он для этого придуман. Хочешь, чтобы разраб максимально четко понимал происходящее и писал предельно строго и безопасно - ну вот Coq. Хочешь проверок - добавляешь в процесс разработки специально предназначенные инструменты: линтеры, статические и динамические анализаторы.
"не плачу за то, чем не пользуюсь"
Бездумное повторение этой мантры и бессмысленно, и чревато.
Итератор с проверкой границ пишется очень просто
Итератор нужно писать каждый раз, каждому программисту. Как вариант - сделать библиотеку, но в простейших вариантах она не будет универсальной, а в мало-мальски сложных быстро растет вероятность неудобства подключения, лишних зависимостей, конфликтов, переусложнения и прочего.
Автоматические проверки достаточно реализовать один раз в каждом компиляторе, затем их сможет применять любой, когда захочет, без поиска и подключения дополнительных библиотек.
вы неявно предполагаете, что разработчик не знает
Я достаточно явно утверждаю, что подавляющее большинство разработчиков себя переоценивает.
Хочешь проверок - добавляешь в процесс разработки специально предназначенные инструменты
Описанные проверки адекватно реализуются только на уровне компилятора. Когда они навешиваются сверху - получается уродливо, менее надежно, и платить в итоге приходится гораздо больше.
В debug ведь все эти проверке добавляются, в release удаляются. Т.е., по сути, это всё уже есть, но программисту не даётся выбирать места кода, где их оставлять/отключать, да?
Именно так. По сути, в опциях компилятора и соответствующих прагмах нет никаких "debug/release" - каждая опция включает свой набор проверок, но у популярных компиляторов это управление и чрезмерно грубо, и не позволяет задействовать многие проверки, которые компилятору было бы несложно вставлять самому.
Я пробую делать свой язык программирования и виртуальную машину к нему. Идея такая же - созданный код долго тестируется в реальных задачах в ВМ с кучей проверок. И если всё норм, то все проверки удаляются. Что-то не слышал о таком нигде, ни про какой язык. Наверно, есть какие-то компиляторы, переводящие интерпретируемые языки как можно ближе к железу.
Насколько я помню, lifecycle optimization собирались заложить в clang, когда он был еще темой кандидатской, но потом это выпало. Да и в Java что-то такое есть: код может быть перекомпилирован в зависимости от того, какая ветка исполнения горячая.
Стоит ли только для этого делать свой? Не проще адаптировать существующий?
Не только для этого. Вижу выбор из двух вариантов - или программист постоянно везде накладывает гарантии (Раст), или же не напрягаясь создаёт программу и потом легко исправляет ошибки при запусках, так как ВМ страхует. Пока не выбрал одно, попробую сочетать оба.
Например, одна из первых идей - IDE сразу укорачивает вектор до количества элементов в нём, когда программист сохраняет адрес этого вектора или его элемента, чтобы при добавлении нового возникала ошибка при использовании этого уже недействительного адреса.
С одной стороны, должен избегать UB, а с другой - если использует UB или implementation defined фичи языка, то он это делает специально, зная, что получится.
"Специально, зная, что получится" можно использовать implementation-defined behavior – конкретная реализация документирует свое поведение и обещается документации соответствовать. UB – это undefined behavior, никаких гарантий никто не даёт. Это всегда так было.
Не гарантируется, но обычно соблюдается. Есть две вещи, которые формально UB, но лично мной используются:
целочисленное знаковое переполнение. Ну просто потому, что в дикой природе не 2's complement представление знакового числа почти не встречается.
формально бесконечный цикл. Компилятор часто не может достоверно доказать конечность цикла, например, если вы считаете теорему Ферма с выходом из цикла по a^n + b^n == c^n С точки зрения языка бесконечный цикл без сайд-эффектов (например, чтение-запись volatile переменных) это UB и при ключе -О3 компилятор его скорее всего уберет, но иногда надо побрутфорсить.
Целочисленное знаковое переполнение - это настоящее UB, а не implementation defined, как вы пытаетесь представить. И компилятор с ним может творить интересные вещи, например сделать конечный цикл бесконечным. Не смотря на то, что процессор 2's complement.
Я знаю, что это UB, о чем прямо и написал. Ну и -О3 такой коварный ключ, надо смотреть, что там накомпилировалось. Ещё clang агрессивнее gcc, он начинает шашкой махать с -Og. Вообще ждем 27, где обещали в очередной раз обещали ввести 2's complement в стандарт С.
Тогда зачем же вы используете это UB? Может надежнее сделать ассемблерную вставку?
Читается лучше, а выше -О2 для своего кода не ставлю просто потому, что не настолько отпечатан у меня в сердце стандарт :)
Ок, тот же самый пример: конечный цикл бесконечным c -O1 и -O2.
UB это UB при любом уровне оптимизация, иногда даже при -O0.
(ещё один аргумент за то, чтобы определить поведение через -fwrapv или -fno-strict-overfow)
Ну и -О3 такой коварный ключ, надо смотреть, что там накомпилировалось.
Проверка на переполнение через if (a + b < 0)
может выкидываться на -O1 (пример отсюда).
Если используете UB, то не удивляйтесь носовым демонам
ИМХО, языку С++ уже ничего не поможет - именно из-за огромного груза обратной совместимости. То что добавляют новые фичи - это даже интересно, наблюдая за этим процессом можно учиться тому, что и как при проектировании новых языков делать надо а что и как не надо. Видно например, какие решения многолетней давности приводят к проблемам.
Carbon и Circle - довольно интересные разработки. Carbon - развитой системой дженериков с концептами, Circle - императивным метапрограммированием. Хотя последний стремится быть слишком похожим на С++ (вероятно чтобы было проще переносить код), из-за чего там уже сейчас прослеживается немало ошибок дизайна.
Carbon - развитой системой дженериков с концептами
Ну конкретно с карбоном я дела не имел, но моё ИМХО состоит в том, что модные нынче разновидности дженериков, которые требуют ручного прописывания всех трейтов, представляют из себя наихудшее сочетание - они одновременно излишне вербозны и хромают в плане функционала (причём второе является следствием первого). Впрочем, в карбоне, насколько я вижу, имеются и старые добрые шаблоны.
С другой стороны в С++ не вылетит ошибка компиляции, пока не произойдет инстанцирование шаблона.
Это неудобно пользователям библиотеки: из заголовка функции/шаблона не понятно, что в нее можно передавать.
Это особенно не удобно разработчикам библиотек: приходится писать тесты компиляции на все возможные случаи, и всё-равно иногда не получается покрыть все варианты.
Эту проблему пытались решить через SFINAE (инопланетная технология), и сейчас пытаются решить через концепты. Это говорит о том, что возможно в С++ (до концептов) и есть наихудший вариант шаблонов/дженериков.
А ваш пример вполне себе работает через динамическую диспетчеризацию (dyn Trait), просто её нужно указать явно. Если не указывать, то происходит мономорфизация до типов usize и f32, а два типа не равны друг другу по определению.
Ну я прямо сейчас не могу попробовать, но что-то мне подсказывает, что dyn
означает рантайм диспатч, а это в свою очередь означает примерно те же проблемы, что в C++ с использованием указателя на функцию вместо шаблонного параметра - в частности, невозможность инлайнинга кода.
Эту проблему пытались решить через SFINAE (инопланетная технология), и сейчас пытаются решить через концепты. Это говорит о том, что возможно в С++ (до концептов) и есть наихудший вариант шаблонов/дженериков.
Опять же, возможность использовать утиный подход там, где он очевидно выгоден (с опциональными ограничениями через SFINAE или концепты), куда лучше, чем принципиальная невозможность его использовать.
Я потому и написал "до концептов", что они меняют дело. Но минусующие читают по диагонали..
Да, динамическая диспетчеризация = рантайм диспатч, я думал это понятно из названия.
Кстати, если компилятор заинлайнит функцию test из примера, то он разворачивает динамическую диспетчеризацию в статическую, и дальше может инлайнить input. К сожалению, нет никаких гарантий, что он так сделает.
Опять же, возможность использовать утиный подход там, где он очевидно выгоден (с опциональными ограничениями через SFINAE или концепты), куда лучше, чем принципиальная невозможность его использовать.
Утиный подход сильно увеличивает время компиляции (думаю очевидно почему), выдает огромные простыни текста при ошибках (по тем же причинам), и приводит к интересным багам.
Так что у него есть свои плюсы и минусы, просто минусы редко обсуждают.
В плюсах-то оно статически работает, так что dyn тут вообще не вариант.
в карбоне, насколько я вижу, имеются и старые добрые шаблоны
Такие же монструозные как и в C++? :-(
Ответил вам там.
Уход от реальных проблем в политику. На пороге 2025 год, в стандартной библиотеке всё еще нет средств доступа к СУБД, ведению логов и построению сетевых служб.
Вот чего не стоит, так это набивать стандартную библиотеку сущностями более высокого уровня. API работы с СУБД, ведение логов, ядро служб - всё это уже реализации задач и не относятся к основе языка и её базовых библиотечных функций.
Да, конечно круто, когда продумывают и этот уровнень, но не все должны всё делать за других. Берём и контрибьютим. Если там не кросс и отказываются делать кросс, и он нужен - форкаем и делаем. Надо же порой что-то делать полезное для всех, а не только компоновать готовые решения.
Сомнительный подход, "бери стороннюю реализацию" - так можно сказать про любой компонент. Вспомним, что STL изначально тоже не была частью стандартной библиотеки, и в 1990-х годах существовало множество реализаций. Работа с датами появилась вообще в C++20, хотя казалось бы, важнейшая часть.
Критерием включения в стандартную библиотеку является не пуризм адептов, а необходимость использования в приложениях. Можно ли представить промышленное приложение не ведущее логов? Можно ли за рамками embedded представить приложение, которое не взаимодействует с другими?
Вопросы риторические, я не вижу у адептов чистоты желания их обсуждать, только поводы отбрехаться.
Вам на самом деле не нужна стандартная библиотека для, например, ведения логов - вам нужна хорошая библиотека для ведения логов. Хорошая != стандартная
Нам нужна хорошая реализация в составе стандартной
Так не бывает: будет или стандартная или хорошая. Иногда (редко) хорошая превращается в стандартную
Стандартная же не может стать хорошей постепенно из-за обратной совместимости
QR-коды-то хоть есть?
Я при работе с С++ пользуюсь Qt (а иногда, если чисто для винды - даже MFC) и как правило вообще не испытываю потребности в стандартной библиотеке:)
как по мне, в стандартной библиотеке C++ реально базовых вещей не хватает, какие там логи и базы данных.. та же нормальная поддержка работы со строками в Unicode, например. или работа с сетевым стеком. вот чего там ожидаешь, а приходится использовать 3rd-party либы для абсолютно базового функционала.
Ну писал же Сам Он: "Remember the Vasa!"
https://www.stroustrup.com/P0977-remember-the-vasa.pdf
Но я так понимаю что "дедушка старый уже, дедушке под 80, чё это он молодежь поучать вздумал на старости лет?"
Первое правило бойцовского к... комитета - не говорить о самом важном. Второе правило комитета - нигде не говорить о самом важном. Дедушка правила знает.
В тексте стандарта ABI нет? Нет. Страуструп об ABI старается не говорить? Старается. Может быть, есть документ а-ля C99 Rationale, где говорилось бы о сохранении ABI как о цели №1? Конечно, нет (и в самом C99 Rationale этого тоже нет). Какой язык на букву R назвал Страуструп в связи с АНБ и безопасностью? Ruby*.
В общем, в его тексте про "path to something that could destroy C++" самое важное как обычно не затрагивается, а в этой статье оно есть.
* Выглядит иронично, но, справедливости ради, в первой версии документа АНБ в одном месте Rust пропустили, Страуструп процитировал этот отрывок.
Ничего, тут вон уже набежали желающие запихнуть в std
средства для работы с БД и написания "сетевых служб" (что бы это ни значило).
В смысле набежали? Там комитет пилет нетворкинг уже который год, как блокер сделали экзекуторы. Может наконец их примут, следом нетворкинг приедет.
Но вообще вы странный конечно, стримы вам в стандарте не мешают хотя обычного файлового си апи хватает, дальше можете сами 100500 оберток сделать. В той же логике стэк и очередь - зачем это ж адаптеры, сами пишите.
Говорить что что не нужно в стандарте только потому что оно вам не нужно сегодня это очень странно.
Скажите ещё юникод не нужен, нормальное файловое апи мне бы тоже пригодилось бы вместо стримов. Не надобность логирование обосновать можете? Стэктрэйсы наконец завезли, но вам конечно это не нужно. Кто б ещё жисон бы пропихнул это уже давно индустриальный стандарт, но не для с++ очевидно. Хрен с ним хттп, хотя бы юриков бы ещё подвезли, но вам не нужно вы уже говорили что сеть вам не нужна. Почему вы тогда не против путей? 13 лет жили без трэдов и тут на тебе подвезли, зачем?
Я вот на днях попробовал экспектед, разочаровался. Мне кажется мертворожденная абстракция. Тип ошибки всего один - это значит что туда либо инт пихать а потом свичиком его проверять либо вариант, но тогда нифига не удобно вариант в качестве ерора у экспектед как то коряво выходит и бойлерплэйт кода становиться больше чем толку от этого экспектед. Я тестил на простом патерне обрабатывать один тип ошибки по месту остальные сконвертировать в эксепцию, получается примерно так же плохо как и с кодами ошибок. Обрабатывать все ошибки я могу и без экспектед на кодах, преобразовать все в эксепцию я тоже могу без него, а вот то зачем оно нужно как раз и не особо хорошо получилось. Это я к тому что я не все части библиотеки считаю полезными вот привел на мой взгляд неудачный пример.
Я вот правда соглашусь что прибивать гвоздями конкретные реализации, а не как в исконном значение стандарта - интерфейсы это плохо. Например вместо
void xxx(std::vector<int>)
Было бы намного правильнее стандартизировать
void xxx(std::vector<int> auto)
Т.е. концепты + интерфейсы для передачи между модулями, а конкретную реализацию можно вообще не требовать. Тогда ваш аргумент про библиотеки будет иметь смысл. Сколько бы проблем это порешало, как минимум большинство если не все связанные с аби.
Я себе, если честно, слабо представляю что-то в std
такое, чтобы без подключения каких-то сторонних библиотек работало бы со всеми БД на свете (а если надо что-то подключать, то зачем std
?). А что такое "написание сетевых служб" я и вовсе не знаю - слишком расплывчатое понятие. Просто работа с сетью штоле? Или что-то ещё подразумевается? Нипанятна.
Скажите ещё юникод не нужен, нормальное файловое апи мне бы тоже пригодилось бы вместо стримов. Не надобность логирование обосновать можете? Стэктрэйсы наконец завезли, но вам конечно это не нужно. Кто б ещё жисон бы пропихнул это уже давно индустриальный стандарт, но не для с++ очевидно. Хрен с ним хттп, хотя бы юриков бы ещё подвезли, но вам не нужно вы уже говорили что сеть вам не нужна. Почему вы тогда не против путей? 13 лет жили без трэдов и тут на тебе подвезли, зачем?
А теперь посмотрите на стандартные реализации этих штук в Java, Python. Заметили что-то? Правильно, стандартными реализациями никто не пользуется. Нет, ладно, файловые операции в Java - ok, но с какого раза? В чём проблема скачивать дополнительные библиотеки? Я лично не вижу проблем. Но зато вот изменения добавляются в разы быстрее и не проходят все стадии отрицания принятия комитетом старых пердунов. JSON и прочие свистелки нужны в языках, программы на которых пишутся за 1 минуту, чтобы быстро проверить гипотезу или что-нибудь кустарно автоматизировать и не хочется ради 1 минуты полчаса искать список библиотек для скачивания. С++ не такой язык.
Имхо мы наблюдаем начало заката C++.
В отличие от pure C, который продолжит жить в микроконтроллерах.
А весь этот несовместимый зоопарк С++ подобных уйдет со временем.
Его заменит Rust в массе и частично Go, пусть и потребуются десятки лет.
Но как и Cobol доисторические ошметки legacy на C++ еще долго будут существовать.
Имхо мы наблюдаем начало заката C++.
Это уже середина, ближе к концу. Началось всё лет 10-15 назад, но очень многие за деревьями не видели леса, да и сейчас ещё не все увидели
В отличие от pure C, который продолжит жить в микроконтроллерах.
Не факт: выпилить его из микроконтроллеров может оказаться даже проще. Как только что-то более безопасное появится, то на него все сразу сбегут - из-за специфики эмбеды в виде ненужности обратной совместимости
Похороны C++ - это как похороны винды. 20 лет уже хоронят.
Скажите, а есть ли какой-то коммитет или рабочая группа в ISO которая работала бы над уменьшением числа фич языка C++ ?
Но ведь это сломает священную обратную совместимость
У меня ничего не сломает. Я и 5% фич не использую. Предлагаю начать урезать осетра.
Разные люди не используют разные 5%.
А так, если хочется урезать осетра, то имеется С-- (Си с двумя минусами). C--. Первое знакомство
И для Git заодно
Ну снизу я бы ограничил число лагерей числом областей применения языка. А сверху... Ну умножим оптимистично нижнюю границу на 4.
Когда вновь и вновь запускают шарманку про "не ломать ABI в частности и обратную совместимость в целом" у меня один вопрос: кто мешает компаниям зафиксировать версию компилятора и продолжать им компилировать свой говнокод? Почему с Python 2.7 -> 3.5 этот трюк получился, а с С++ не получится?
Пример эволюции Python 2 -> 3 без обратной совместимости, создал очень много проблем с пакетами, которых просто не было под 3-ю версию в моменте. Да, было тяжело.
Но в то же время этот переход, параллельно вырастил много молодых (и не очень) разработчиков, которые в итоге переписали всё и неявно унаследовали компетенции по этим проектам от старых мейнтейнеров, которые не готовы были к изменениям в силу разных причин. В итоге большинство библиотек не умерли, а переродились.
Появилось очень много подходов и инструментария, обучающего материала, "свежих" разработчиков, и возможность развивать язык дальше в конце концов. Это похоже на экономику и это не так плохо. Важно грамотное управление проектом (стандартом).
В рядах C++ разработчиков как будто уже накопилась критическая масса, которая готова начать переход. Можно сделать инструментарий для упрощения миграции.
Но пока остается вопрос - куда переходить в случае с С++, что ломать и строить в первую очередь.
В Rust по-умолчанию зависимости подтягиваются с crates.io, причём тут GitHub?
Опять скажу, что не люблю Го, но давайте предерживаться фактов: пакеты совершенно необязательно таскать с Гитхаба. Вообще говоря, наличие стандартной системы сборки это скорее достоинство, чем недостаток, при этом как минимум конкретно Го гвоздями к системе сборки не прибит, если хотите собирать Го Базелем – собирайте, это вполне себе рабочий вариант.
определенная консервативность и совместимость это не баг, это фича
Два лагеря C++