Сейчас ведётся много споров и дискуссий о будущем C++.
Не только на Reddit и одном оранжевом веб-сайте, но и совершенно точно на официальных заседаниях комитета по стандарту C++.
Абсолютное состояние (языка C++)
Похоже, мы находимся в следующей ситуации:
-
Evolution Working Group (EWG) языка C++ как раз достигла консенсуса по внедрению P3466 R0 - (Re)affirm design principles for future C++ evolution:
Это означает отсутствие поломок ABI, сохранение совместимости компоновки с кодом на C и предыдущими версиями C++.
Также это означает отсутствие «виральных аннотаций» (например, аннотаций времени жизни)1.
Удвоение усилий по множеству несовместимых задач, например, отсутствия поломок ABI и принципа zero overhead2.
Плохо это или хорошо, но это (в буквальном смысле) удвоение усилий по развитию текущей траектории языка C++.
1. Если быть циничным, то это можно интерпретировать как явное «не одобряем» в отношении аннотаций времени жизни Rust и предложения Safe C++ Шона Бакстера. Если же умерить цинизм, то это, по крайней мере, трезвое осознание того факта, что отрасль не хочет заниматься рефакторингом старого кода.
2. «Мы не платим за то, чем не пользуемся». По сути, старая фича C++ может повлиять на производительность среды исполнения, только если вы активно её используете. Это не совсем совместимо со стабильным ABI, потому что стабильный ABI (понимаемый как фича C++) исключает определённые улучшения производительности.
Тем же временем:
-
Правительство США хочет, чтобы люди перестали пользоваться C++:
Агентство по кибербезопасности и защите инфраструктуры (CISA)
Всё именно так: различные ветви правительства США выпустили статьи, отчёты и рекомендации, чтобы предупредить отрасль о нежелательности использования небезопасных по памяти языков.
-
Всевозможные крупные технологические игроки осваивают Rust:
Microsoft переписывает базовые библиотеки на Rust.
Google, похоже, приняла решение о переходе на Rust и начала работу над инструментом для обеспечения двунаправленной функциональной совместимости между C++ и Rust.
AWS использует Rust.
и так далее.
Кстати, о больших технологических компаниях: а вы заметили, что Херб Саттер уходит из Microsoft, а MSVC, похоже, не торопится реализовывать фичи C++23 и просит сообщество о расстановке приоритетов.
Произошло печально известное пражское голосование по ABI (если вкратце: «C23 не поломает ABI, и непонятно, будет ли это когда-либо сделано»). Google, предположительно, существенно снизила уровень своего участия в процессе разработки C, и вместо этого начала работать над собственным языком-потомком C++. Компания даже выпустила сводку с перечислением всех проблем, которые у неё возникали при попытках улучшения C++3.
В сообществе ходят уже всем известные истории людей, изо всех сил старавшихся участвовать в процессах комитета по стандарту: их просто пережёвывали и выплёвывали.
-
Модули по-прежнему не реализованы. Мы уже модули?4
«Профили безопасности» всё ещё находятся в странном состоянии и у них нет готовой реализации; есть попытки добавить определённую долю безопасности в уже написанный код на C++ с минимизацией изменений в этом коде. Сам Шон Бакстер занял позицию против профилей и сказал, что C++ «недостаточно покрыт спецификациями».
3. Думаю, Carbon гораздо интереснее, чем его воспринимает большинство. Возможно, я как-нибудь напишу об этом пост.
4. Мы к этому идём! Похоже, буквально за несколько дней до публикации статьи в GCC добавили поддержку модуля std
. Это может занять длительное время, и кто знает, какой будет экосистема, но это уже прогресс!
Не знаю, как вы, но если бы я смотрел на всё это, как внешний наблюдатель, то мне бы определённо казалось, что C++, по сути, разваливается на куски, и что большое количество людей потеряло веру в способность комитета по C++ каким-нибудь образом решить все эти проблемы5.
5. Разваливается на куски сейчас? Ну, это зависит от того, что иметь в виду. Весь этот код на C++ никуда не денется. То есть в этом смысле нет. Код на C++, по крайней мере, продолжит существовать.
Две культуры
Похоже, люди ищут другие решения.
Возьмём Google. Эта компания, очевидно, навсегда потеряла веру во «всемогущий процесс» с момента голосования по ABI. Это не потеря веры в сам язык, Google обладает одной из крупнейших в мире кодовых баз на C++, и она послужила компании отличную службу. Это потеря веры в способность языка эволюционировать в условиях нарастания давления с разных сторон (потенциальные правительственные постановления, языки-конкуренты, потребность у основных игроков в повышении производительности и гарантиях безопасности и так далее).
Так в чём же проблема? Почему C++ просто... не меняется?
Ну, понять это легко. Достаточно прочитать то, что написал Херб Саттер в своей статье о профилях:
«Мы должны минимизировать потребность в изменении готового кода. Десятки лет опыта показали, что большинство пользователей с большими кодовыми базами не могут и не будут менять даже 1% строк кода, чтобы он соответствовал правилам строгости, даже из соображений безопасности, только если их не заставят это сделать правительственные требования», — Херб Саттер.
Круто. Кого-то это удивило? Не думаю.
Для контраста приведём биографию Чендлера Каррета со страницы члена WG21:
Я руководил проектированием инструментария и систем автоматизированного рефакторинга C++, построенных на основе Clang и в дальнейшем ставших частью проекта Clang. […]
В Google я руководил проектом по масштабированию инструментов автоматизированного рефакторинга на основе Clang до объёма всей нашей кодовой базы (более ста миллионов строк кода на C++). Мы можем анализировать и применять рефакторинги во всей кодовой базе всего за двадцать минут.
Заметили что-нибудь? (Конечно, заметили, я это специально выделил.)
«Автоматизированный инструментарий». Только ведь дело не ограничивается лишь им, это лишь один яркий пример.
По сути, мы видим конфликт между двумя разительно различающимися лагерями пользователей C++:
Относительно современные способные технологические корпорации, осознающие, что их код — это ценное имущество. (Здесь можно не ограничиваться только big tech. Любой вменяемый C++-стартап тоже относится к этой категории.)
Все остальные. Любая древняя корпорация, в которой люди до сих пор спорят о том, как расставлять отступы в коде, а один молодой инженер умоляет своё руководство позволить ему настроить линтер.
Одна из этих групп будет способна справиться с миграцией практически беспроблемно, и это та группа, которая способна создать свой стек C++ на основе исходников с версионностью, а не та группа, которая по-прежнему использует готовые библиотеки из 1998 года.
Эта способность создания целого стека зависимостей на основе исходников с версионностью (предпочтительно с автоматизированными тестами) — вероятно, самая важная разделительная линия между двумя лагерями.
Разумеется, на практике это градиент. Могу только представить, сколько пота, крови, денег и труда потребовалось, чтобы превратить кодовые базы компаний big tech из ужасающих кусков грязи в относительно управляемые, собираемые, чуть менее пугающие куски грязи с надлежащим контролем версий.
Обладая послезнанием, легко подумать, что всё это было неизбежно: что существует чёткое разделением между потребностями корпораций наподобие Google (которые используют относительно современный C++, имеют автоматизированный инструментарий и тестирование, а также современную инфраструктуру) и желанием (очень сильным) обратной совместимости.
Если смотреть трезвым взглядом, то окажется, что идея единого, свободного от диалектов и унифицированного C++, похоже, мертва уже многие годы6. У нас есть как минимум две основных разновидности C++:
Любой хотя бы отдалённо современный C++. Всё, что можно собрать из исходников с версионностью при помощи специального чистого и унифицированного процесса сборки, который хотя бы немного сложнее, чем сырой CMake, и который хотя бы с натяжкой можно назвать работающим. Добавить какие-нибудь статические анализаторы, форматировщик, линтер. Любой стандарт обеспечения чистоты и современности кодовой базы. Вероятно, хотя бы C++17, с
unique_ptr
,constexpr
, лямбдами,optional
, но смысл не в этом. Самое главное — это инструментарий.Легаси-C++. Всё, что не является первым пунктом. Любой C++, который хранится в древних запылённых серверах банка средних размеров. Любой C++, который зависит от ужасно устаревшего куска скомпилированного кода с утерянными исходниками. Любой C++, который развёрнут на pet-сервере; чтобы развернуть его где-то ещё одному инженеру потребуется целый месяц, чтобы хотя бы разобраться во всех его косвенных зависимостях, конфигурациях и переменных окружения. Любая кодовая база, которая считается местом возникновения затрат. Любой код, в котором сборка любого используемого двоичного файла из исходников требует чего-то большего, чем нажатие на несколько кнопок, а то и вовсе невозможна.
6. Жила ли она вообще когда-нибудь, с этими всевозможными компиляторами и их собственными расширениями — это уже другой вопрос.
Как вы, наверно, заметили, главное различие заключается вообще не в самом C++. Разница заключается в инструментарии и в способности выполнять сборку из исходников с версионностью чистым, чётко определённым образом. В идеале даже в способности развёртывать код без необходимости запоминать тот один флаг или переменную окружения, которую обычно добавлял предыдущий разработчик, чтобы всё не поломалось.
То, насколько кодовая база Google соблюдает идиомы «современного» C++, вторично по сравнению с качеством инструментария и того, можно ли собирать код из исходников.
Многие скажут, что инструментарий — это не сфера ответственности комитета по стандарту C++, и они будут правы. Инструментарий — не сфера ответственности комитета по стандарту C++, потому что комитет отрекается от любой ответственности за него (он сосредоточил усилия на спецификациях языка C++, а не на конкретных реализациях)7. Это сделано с умыслом, и их сложно винить, учитывая багаж легаси. C++ — это стандарт, унифицирующий разные реализации.
7. Впрочем, это немного несправедливо. Существует исследовательская группа SG15, занимающаяся инструментарием. См. например, этот пост. Разумеется, весь процесс по-прежнему сосредоточен на написании статей, а не, например, на выпуске канонического менеджера пакетов.
Тем не менее, если уж язык Go и сделал что-то правильно, так это упор на инструменты. По сравнению с ним C++ находится в доисторической эпохе, когда ещё не изобрели линтеры. C++ не имеет унифицированной системы сборки, у него нет ничего даже близко похожего на унифицированную систему управления пакетами, его невероятно сложно парсить и анализировать (а это ужасно мешает инструментарию) и он ведёт пугающе неравный бой с законом Хайрама по поводу каждого изменения, которое нужно внести.
Между двумя лагерями есть огромная разрастающаяся пропасть (хороший инструментарий, беспроблемная сборка из исходников против плохого инструментария и невозможности сборки из исходников); честно говоря, я не вижу никаких подвижек к уничтожению этой пропасти в обозримом будущем.
Комитет по C++ изо всех сил стремится поддерживать обратную совместимость, чего бы это ни стоило.
Кстати, я даже не особо против этого! Обратная совместимость — это очень важно для многих людей, и на то у них есть веские причины. Но других она особо не волнует. Не важно, какая из групп «права»: просто их взгляды несовместимы.
Последствия
Именно поэтому ситуация с профилями именно такова: профили безопасности не предназначены для решения проблем современных, технологически продвинутых корпораций, пишущих на C++. Они нужны для улучшений без необходимости внесения изменений в старый код.
Аналогичная ситуация и с модулями. Пользователь должен иметь возможность «просто» импортировать файл заголовка как модуль, и при этом не должно возникать никаких проблем с обратной совместимостью.
Разумеется, всем нравятся фичи, которые можно просто добавить и которые вносят улучшения без необходимости менять старый код. Но достаточно очевидно, что эти фичи проектировались с учётом в первую очередь «легаси-C++». Поэтому любая фича, которая потребует миграции с легаси-C++ — не вариант для комитета по C++, ведь, как сказал Херб Саттер, по сути, нельзя ожидать, что люди будут выполнять миграцию.
(Повторюсь, создание фич с учётом легаси-C++ — это не плохо. Это вполне разумное решение.)
Именно об этом я стараюсь не забывать, читая статьи по C++: существует две крупные аудитории. Одна предпочитает современный C++, вторая — легаси-C++. У этих двух лагерей есть огромные разногласия, а многие статьи написаны с учётом потребностей конкретной группы.
Очевидно, это приводит к тому, что каждый говорит о своём: что бы ни думали люди, на самом деле профили безопасности и Safe C++ стремятся решать совершенно разные проблемы для разных аудиторий, а не одинаковые.
Комитет по C++ предпринимает усилия к тому, чтобы эта пропасть не расширялась. Предположительно, именно поэтому любые движения в сторону Safe C++ Шона Бакстера для них неприемлемы. Это радикальное изменение, способное создать фундаментально новый способ написания кода на C++.
Разумеется, есть ещё и вопрос, не являются ли отдельные члены комитета по стандарту C++ просто крайне упёртыми людьми, хватающимися за соломинку, чтобы помешать эволюции, с которой они не согласны эстетически.
Я далёк от того, чтобы кого-то обвинять, но не в первый раз слышу, что комитет по C++ использует двойные стандарты вида: «Чтобы утвердить это предложение, мы ожидаем увидеть полную работающую реализацию для множества работающих компиляторов, но с радостью занимаемся отдельными крупными проектами (например, модули и профили), не имеющими функционального доказательства реализации концепции».
Если это так (не могу сказать с уверенностью), то нельзя сказать, как долго ещё C++ будет двигаться по этому пути без гораздо более серьёзного разрыва между двумя лагерями.
И мы ведь даже ещё не касались огромной кучи проблем, которую бы вызвала поломанная совместимость ABI.
Комментарии (89)
kompilainenn2
05.12.2024 07:36По тексту есть номера сносок, но текста сносок нет в статье
Limansky
05.12.2024 07:36они есть и идут прямо под текстом, в котором используются сноски
kompilainenn2
05.12.2024 07:36Блин, а я подумал, что это ошибка форматирования просто и это обычный текст
Alex_Malin
05.12.2024 07:36я тоже) лучше не придумывать новое оформление, а делать как все, как привыкли хабровчане
firehacker
05.12.2024 07:36По-моему, у огромного числа людей существует фатальное заблуждение: им внушили, и они теперь считают за норму ситуацию, и считают, что это вполне неплохо и даже хорошо, если стандарт (какой бы то ни было — хоть на ЯП, хоть на резьбу болтов) меняют каждые пару лет. В идеале, стандарт вообще не должен меняться. В реальном мире (сейчас набегут сторонники «реального мира») было бы терпимо, если бы по исключительным поводам и основаниям стандарт допускалось пересматривать и менять раз в лет 10—15.
Стандарт, в котором уже десять лет закралась и сидит не-фатальная ошибка, лучше, чем «идеальный» стандарт, который меняют каждый день — такова моя система ценностей. Поэтому мне больно читать про всё то, что делается с С++ в последние годы.
Demevag
05.12.2024 07:36А USB какого стандарта вы используете?
CrashLogger
05.12.2024 07:36Вот версии USB как раз и выходят раз в 10 лет, с ним все нормально. Хотя в последний, конечно, напихали слишком много всего.
Demevag
05.12.2024 07:36USB 1.0 - 1996
USB 1.1 - 1998
USB 2.0 - 2000
USB 3.0 - 2008
USB 3.1 - 2013
USB 3.2 - 2017
USB 4 - 2019
USB4 2.0 - 2022
Что-то не вижу тут разницы в 10 лет
Gryphon88
05.12.2024 07:36Возможно, это просто травматический опыт (я пытался выучить плюсы как второй язык в пару к чистому С и толком не смог), но, имхо, изменение стандарта это нормально, если время от времени сбрасывать обратную совместимость. При разработке "Цивилизации" был хороший принцип: в новой игре треть старого, треть нового, треть измененного, и поэтому поиграв в 2 цивилизацию, можно легко вникнуть в 3 и чуть сложнее в 4 (если пропустил 3). Попытки тащить огромный груз совместимости приводят к тому, что кажется, будто при программировании на С++ пытаешь играть сразу во все игры серии с непонятным переплетением механик.
JediPhilosopher
05.12.2024 07:36В Питоне вон эту совместимость так сломали, что потом 15 лет расхлебывали. И вроде только-только расхлебали, во всяком случае я уже избавился наконец от второго питона и не попадаю в ситуации, когда половина нужного софта и библиотек написаны под второй, а половина под третий.
Думаю, многие на это посмотрели и решили, что так не хотят.
bigbamblbee
05.12.2024 07:36Ты действительно ожидаешь адекватности от этих людей? Есть такой принцип, согласно которому, зная 20% функционала, можно получить 80% результата, и он ни смотря ни на что - работает. Этот принцип не говорит ни в коем случае о том, что нужно остановиться в развитии или не изучать более полно нужный тебе инструмент, но я более чем уверен, что подавляющая часть комментаторов ниже и выше, этих замечательных людей из секты свидетелей раста и ему подобных, используют 80% функционала, для того чтобы получить 20% результата. Других разумных объяснений их поведению и мышлению нет. Просто очень странно, что чуваки, которые пишут 0.01% всего кода в мире, постоянно пытаются диктовать, как и каким образом писать оставшиеся 99.99% кода всем остальным программистам, которых всё устраивает.
maaGames
05.12.2024 07:36Так стандарт и не меняется. С'99 остаётся до сих пор C'99. C++14 стался C++14 даже после выхода C++17. Они не меняют стандарт языка, а выпускают новый стандарт. Это другое.
ahabreader
05.12.2024 07:36Они не меняют стандарт языка, а выпускают новый стандарт.
Если буквоедствовать, то можно возразить, что магазин стандартов ISO старые версии изымает из продажи и помечает их как "отозванные". На что можно возразить - а магазин стандартов IEC - как "пересмотренные" и продолжает продавать. Затем можно возразить им всем: ребята, ну кто покупает
WinRARстандарт, пользуйтесь черновиками. И не испытывайте лишнего пиетета перед стандартом, вон, Linux активно использует расширения GCC и Линус ценности в стандарте не находит, на C++ зачастую тоже пишут под GCC/Clang: "V8 officially dropped support for MSVC" (тыц), "Firefox 63 onward MSVC is not supported" (тыц).maaGames
05.12.2024 07:36Если буквоедствовать... Тогда претензия не к тому, что издают новый стандарт, а что отзывают старый. Почему отзывают? Потому что он не удовлетворяет современным требованиям. Что делать, чтобы не отзывать? Вместо выпуска нового, надо изменить старый стандарт! И вот в этом случае мы просто берём и копи-пастим изначальную претензию, которая уже без придирок будет соответствовать ситуации.
Biga
05.12.2024 07:36Александреску когда-то пилил D, но чёт не слышно про него ничего...
a-tk
05.12.2024 07:36Он, к сожалению, умер под эффектом второй системы
ahabreader
05.12.2024 07:36Последняя крупная новость была в январе, об ответвлении под названием "язык OpenD". Если про D вспоминать в контексте статьи, то у него есть
@safe
-атрибут (который, как пишут, на main() охватывает программу целиком), но unsafe-by-default для CISA недостаточно, судя по их таблице: "Memory-unsafe: Assembly, C, C++, C/C++ Header, Cython, D".----
Создатель D отметился на HN (WalterBright) в обсуждении этой статьи.
artemisia_borealis
05.12.2024 07:36Не сказать прям, что умер, но не хайпе уж точно.
Так-то замечательный язык, возможно лучшее из т.н. C-подобных языков. Много очень классных вещей и документация отличная, не говоря о времени компиляции. Помимо компилятора (dmd) есть ещё режим интерпретатора (rdmd). B режим betterC впридачу.
Сообщество довольно активное на самом деле.
ahdenchik
05.12.2024 07:36Активно программирую на D много лет. Жив он.
Но почему-то компании его использование не афишируют - будто стесняютсяa-tk
05.12.2024 07:36У меня сложилось впечатление, что первый D был вполне неплохим языком, но местами со странными вещами (например
x.atomicOp"+="(1)
).Так и не выпустив его в полноценное плавание, Александреску взялся делать вторую версию (улучшенную и исправленную), которая сама уже не выстрелила особо (в смысле не стала сколько-нибудь популярным языком) и утащила за собой первую версию (давайте подождём второй, улучшенной и исправленной), потеряв время.
А жаль. Очень жаль. Искренне жаль.
Siemargl
05.12.2024 07:36Если точнее, то Д1 от Д2 отличается в основном стандартной библиотекой tango vs phobos, язык не так кардинально изменился. Впрочем есть tango для текущего компилятора.
А betterC вполне актуальная и прямая замена С уже сейчас
GBR-613
05.12.2024 07:36Предлагаю переименовать С++ из языка в семейство языков. Такова ведь судьба всех выживших языков древности: нет давно языка LISP, а есть семейство LISP-подобных языков, новые диалекты COBOL не полностью совместимы между собой, и т.д. Вот и давайте решим, что, например, С++11 это один язык, а будущий С++25 - другой. Кому важнее безопасность - пусть делает porting со старого языка на новый, кому не так важна - пусть так и объявит, у нас язык С++11 и живите с этим. И в вакансиях на работу, и в резюме так и указывать.
Это решит очень много споров.
orefkov
05.12.2024 07:36А мне это и нравится в C++: свобода. Когда надо, можешь использовать все плюшки, типа смарт-поинтеров, функциональщины, контейнеров, а надо - спустился до указателей, буферов, до asm. Не нравятся стандартные строки - написал свои. Понадобился свой аллокатор - нет проблем.
А безопасность? Ну, C++ даёт большую силу, а "с большой силой приходит и большая ответственность". И я боюсь, что в погоней за "безопасностью" заберут эту свободу, и просто выкинут всё, что хоть как-то позволяет выстрелить в ногу, и язык превратится в какую-то манную кашку.
"О, смотрите, ножом можно порезаться, давайте отберем ножи. А хлеб пусть нарезанный покупают". Как бы такой подход не довел до всеобщей кастрации, "а то вы же изнасиловать кого-нибудь можете".emusic
05.12.2024 07:36Самое смешное, что наличие низкоуровневых элементов практически никак не мешает добавлению средств увеличения безопасности.
Достаточно внести в компилятор простую и дешевую доработку - и вот он уже автоматически генерирует проверку каждого указателя при каждом его разыменовании. Да, это сразу увеличивает затраты на выполнение, но еще одна простая и дешевая доработка - и эти проверки [не] генерируются для явно указанных фрагментов, или по указанному условию.
Еще одна простая/дешевая доработка - и на каждое использование объекта (перед и/или после использования) компилятор генерирует вызов указанного метода, который проверяет целостность объекта.
Таких несложных доработок можно сделать довольно много, потом оценить, какие из них больше способствуют повышению безопасности, и предложить в Стандарт.
Но разработчики компиляторов предпочитают десятки лет тянуть убогие огрызки подобных средств (каждый свои), и никакой унификацией даже близко не пахнет.
Gryphon88
05.12.2024 07:36Есть риск получить вместо плюсов Java или Python :) Было неявное соглашение для С и С++: программист знает, что он делает. С одной стороны, должен избегать UB, а с другой - если использует UB или implementation defined фичи языка, то он это делает специально, зная, что получится. К сожалению, это соглашение давно нарушается: компиляторы предполагают полное отсутствие UB в коде для агрессивных оптимизаций. Таким образом, ваше предложение нарушает оба основных тренда: "скорость превыше всего" и "я знаю, что я делаю". Ну и до кучи старый принцип "не плачу за то, чем не пользуюсь",
emusic
05.12.2024 07:36Есть риск получить вместо плюсов Java или Python :)
Это как? :) Я пока не предложил никаких функциональных расширений - только автопроверки для повышения безопасности применения существующих. У меня, конечно, есть идеи и по функционалу, но кому они нынче интересны? :)
если использует UB или implementation defined фичи языка, то он это делает специально, зная, что получится.
Так и пусть использует. Если ему действительно нужно разыменовать невалидный указатель - укажет это явно (какими-нибудь прагмами, например), и именно в этом месте автопроверка вставлена не будет.
"скорость превыше всего"
Кому нужна скорость, тот не будет этого использовать - по крайней мере, там, где скорость реально нужна.
"я знаю, что я делаю"
Вот пусть и заявит об этом явно. :) Чтоб в случае обоснованных сомнений можно было включить автопроверки и потыкать его носом в их результаты. :)
В идеале, конечно, такие автопроверки должны навешиваться по умолчанию, и требовать явного отключения, поскольку на C++ уже давно пишет куда больше тех, кто лишь думает, будто знает, а на деле знает недостаточно. Уверен, что знаешь - поставил хорошо видимые в тексте маркеры.
"не плачу за то, чем не пользуюсь"
Здесь ничего не меняется. Если от автопроверок есть выгода в плане раннего обнаружения ошибок - значит, ими пользуются. А если они не способны дать выгоду, их и включать не нужно (но лучше таки отключить включенные по умолчанию).
f33lg00d
05.12.2024 07:36С одной стороны, должен избегать UB, а с другой - если использует UB или implementation defined фичи языка, то он это делает специально, зная, что получится.
"Специально, зная, что получится" можно использовать implementation-defined behavior – конкретная реализация документирует свое поведение и обещается документации соответствовать. UB – это undefined behavior, никаких гарантий никто не даёт. Это всегда так было.
NeoCode
05.12.2024 07:36ИМХО, языку С++ уже ничего не поможет - именно из-за огромного груза обратной совместимости. То что добавляют новые фичи - это даже интересно, наблюдая за этим процессом можно учиться тому, что и как при проектировании новых языков делать надо а что и как не надо. Видно например, какие решения многолетней давности приводят к проблемам.
Carbon и Circle - довольно интересные разработки. Carbon - развитой системой дженериков с концептами, Circle - императивным метапрограммированием. Хотя последний стремится быть слишком похожим на С++ (вероятно чтобы было проще переносить код), из-за чего там уже сейчас прослеживается немало ошибок дизайна.
KanuTaH
05.12.2024 07:36Carbon - развитой системой дженериков с концептами
Ну конкретно с карбоном я дела не имел, но моё ИМХО состоит в том, что модные нынче разновидности дженериков, которые требуют ручного прописывания всех трейтов, представляют из себя наихудшее сочетание - они одновременно излишне вербозны и хромают в плане функционала (причём второе является следствием первого). Впрочем, в карбоне, насколько я вижу, имеются и старые добрые шаблоны.
qwerty19106
05.12.2024 07:36С другой стороны в С++ не вылетит ошибка компиляции, пока не произойдет инстанцирование шаблона.
Это неудобно пользователям библиотеки: из заголовка функции/шаблона не понятно, что в нее можно передавать.
Это особенно не удобно разработчикам библиотек: приходится писать тесты компиляции на все возможные случаи, и всё-равно иногда не получается покрыть все варианты.
Эту проблему пытались решить через SFINAE (инопланетная технология), и сейчас пытаются решить через концепты. Это говорит о том, что возможно в С++ (до концептов) и есть наихудший вариант шаблонов/дженериков.
А ваш пример вполне себе работает через динамическую диспетчеризацию (dyn Trait), просто её нужно указать явно. Если не указывать, то происходит мономорфизация до типов usize и f32, а два типа не равны друг другу по определению.
KanuTaH
05.12.2024 07:36Ну я прямо сейчас не могу попробовать, но что-то мне подсказывает, что
dyn
означает рантайм диспатч, а это в свою очередь означает примерно те же проблемы, что в C++ с использованием указателя на функцию вместо шаблонного параметра - в частности, невозможность инлайнинга кода.Эту проблему пытались решить через SFINAE (инопланетная технология), и сейчас пытаются решить через концепты. Это говорит о том, что возможно в С++ (до концептов) и есть наихудший вариант шаблонов/дженериков.
Опять же, возможность использовать утиный подход там, где он очевидно выгоден (с опциональными ограничениями через SFINAE или концепты), куда лучше, чем принципиальная невозможность его использовать.
qwerty19106
05.12.2024 07:36Я потому и написал "до концептов", что они меняют дело. Но минусующие читают по диагонали..
Да, динамическая диспетчеризация = рантайм диспатч, я думал это понятно из названия.
Кстати, если компилятор заинлайнит функцию test из примера, то он разворачивает динамическую диспетчеризацию в статическую, и дальше может инлайнить input. К сожалению, нет никаких гарантий, что он так сделает.
Опять же, возможность использовать утиный подход там, где он очевидно выгоден (с опциональными ограничениями через SFINAE или концепты), куда лучше, чем принципиальная невозможность его использовать.
Утиный подход сильно увеличивает время компиляции (думаю очевидно почему), выдает огромные простыни текста при ошибках (по тем же причинам), и приводит к интересным багам.
Так что у него есть свои плюсы и минусы, просто минусы редко обсуждают.
cross_join
05.12.2024 07:36Уход от реальных проблем в политику. На пороге 2025 год, в стандартной библиотеке всё еще нет средств доступа к СУБД, ведению логов и построению сетевых служб.
Kingas
05.12.2024 07:36Вот чего не стоит, так это набивать стандартную библиотеку сущностями более высокого уровня. API работы с СУБД, ведение логов, ядро служб - всё это уже реализации задач и не относятся к основе языка и её базовых библиотечных функций.
Да, конечно круто, когда продумывают и этот уровнень, но не все должны всё делать за других. Берём и контрибьютим. Если там не кросс и отказываются делать кросс, и он нужен - форкаем и делаем. Надо же порой что-то делать полезное для всех, а не только компоновать готовые решения.
cross_join
05.12.2024 07:36Сомнительный подход, "бери стороннюю реализацию" - так можно сказать про любой компонент. Вспомним, что STL изначально тоже не была частью стандартной библиотеки, и в 1990-х годах существовало множество реализаций. Работа с датами появилась вообще в C++20, хотя казалось бы, важнейшая часть.
Критерием включения в стандартную библиотеку является не пуризм адептов, а необходимость использования в приложениях. Можно ли представить промышленное приложение не ведущее логов? Можно ли за рамками embedded представить приложение, которое не взаимодействует с другими?
Вопросы риторические, я не вижу у адептов чистоты желания их обсуждать, только поводы отбрехаться.
ahdenchik
05.12.2024 07:36Вам на самом деле не нужна стандартная библиотека для, например, ведения логов - вам нужна хорошая библиотека для ведения логов. Хорошая != стандартная
cross_join
05.12.2024 07:36Нам нужна хорошая реализация в составе стандартной
ahdenchik
05.12.2024 07:36Так не бывает: будет или стандартная или хорошая. Иногда (редко) хорошая превращается в стандартную
Стандартная же не может стать хорошей постепенно из-за обратной совместимостиcross_join
05.12.2024 07:36"Хорошая/плохая" - это для дискуссий о футболе. Инженеры оперируют различными критериями, из которых "минимизация внешних зависимостей", "надежная опробованная методика" и "неограниченная временем поддержка" стоят в топе
NeoCode
05.12.2024 07:36Я при работе с С++ пользуюсь Qt (а иногда, если чисто для винды - даже MFC) и как правило вообще не испытываю потребности в стандартной библиотеке:)
cross_join
05.12.2024 07:36Один из подходов, позволяющих отгородиться от безумия, пример которого описан в статье. На клиентской части - проходит, на серверной стороне - уже совсем не так весело.
geornit25
05.12.2024 07:36как по мне, в стандартной библиотеке C++ реально базовых вещей не хватает, какие там логи и базы данных.. та же нормальная поддержка работы со строками в Unicode, например. или работа с сетевым стеком. вот чего там ожидаешь, а приходится использовать 3rd-party либы для абсолютно базового функционала.
RolexStrider
05.12.2024 07:36Ну писал же Сам Он: "Remember the Vasa!"
https://www.stroustrup.com/P0977-remember-the-vasa.pdf
Но я так понимаю что "дедушка старый уже, дедушке под 80, чё это он молодежь поучать вздумал на старости лет?"ahabreader
05.12.2024 07:36Первое правило
бойцовского к... комитета - не говорить о самом важном. Второе правило комитета - нигде не говорить о самом важном. Дедушка правила знает.В тексте стандарта ABI нет? Нет. Страуструп об ABI старается не говорить? Старается. Может быть, есть документ а-ля C99 Rationale, где говорилось бы о сохранении ABI как о цели №1? Конечно, нет (и в самом C99 Rationale этого тоже нет). Какой язык на букву R назвал Страуструп в связи с АНБ и безопасностью? Ruby*.
В общем, в его тексте про "path to something that could destroy C++" самое важное как обычно не затрагивается, а в этой статье оно есть.
* Выглядит иронично, но, справедливости ради, в первой версии документа АНБ в одном месте Rust пропустили, Страуструп процитировал этот отрывок.
KanuTaH
05.12.2024 07:36Ничего, тут вон уже набежали желающие запихнуть в
std
средства для работы с БД и написания "сетевых служб" (что бы это ни значило).boldape
05.12.2024 07:36В смысле набежали? Там комитет пилет нетворкинг уже который год, как блокер сделали экзекуторы. Может наконец их примут, следом нетворкинг приедет.
Но вообще вы странный конечно, стримы вам в стандарте не мешают хотя обычного файлового си апи хватает, дальше можете сами 100500 оберток сделать. В той же логике стэк и очередь - зачем это ж адаптеры, сами пишите.
Говорить что что не нужно в стандарте только потому что оно вам не нужно сегодня это очень странно.
Скажите ещё юникод не нужен, нормальное файловое апи мне бы тоже пригодилось бы вместо стримов. Не надобность логирование обосновать можете? Стэктрэйсы наконец завезли, но вам конечно это не нужно. Кто б ещё жисон бы пропихнул это уже давно индустриальный стандарт, но не для с++ очевидно. Хрен с ним хттп, хотя бы юриков бы ещё подвезли, но вам не нужно вы уже говорили что сеть вам не нужна. Почему вы тогда не против путей? 13 лет жили без трэдов и тут на тебе подвезли, зачем?
Я вот на днях попробовал экспектед, разочаровался. Мне кажется мертворожденная абстракция. Тип ошибки всего один - это значит что туда либо инт пихать а потом свичиком его проверять либо вариант, но тогда нифига не удобно вариант в качестве ерора у экспектед как то коряво выходит и бойлерплэйт кода становиться больше чем толку от этого экспектед. Я тестил на простом патерне обрабатывать один тип ошибки по месту остальные сконвертировать в эксепцию, получается примерно так же плохо как и с кодами ошибок. Обрабатывать все ошибки я могу и без экспектед на кодах, преобразовать все в эксепцию я тоже могу без него, а вот то зачем оно нужно как раз и не особо хорошо получилось. Это я к тому что я не все части библиотеки считаю полезными вот привел на мой взгляд неудачный пример.
Я вот правда соглашусь что прибивать гвоздями конкретные реализации, а не как в исконном значение стандарта - интерфейсы это плохо. Например вместо
void xxx(std::vector<int>)
Было бы намного правильнее стандартизировать
void xxx(std::vector<int> auto)
Т.е. концепты + интерфейсы для передачи между модулями, а конкретную реализацию можно вообще не требовать. Тогда ваш аргумент про библиотеки будет иметь смысл. Сколько бы проблем это порешало, как минимум большинство если не все связанные с аби.
KanuTaH
05.12.2024 07:36Я себе, если честно, слабо представляю что-то в
std
такое, чтобы без подключения каких-то сторонних библиотек работало бы со всеми БД на свете (а если надо что-то подключать, то зачемstd
?). А что такое "написание сетевых служб" я и вовсе не знаю - слишком расплывчатое понятие. Просто работа с сетью штоле? Или что-то ещё подразумевается? Нипанятна.
mbait
05.12.2024 07:36Скажите ещё юникод не нужен, нормальное файловое апи мне бы тоже пригодилось бы вместо стримов. Не надобность логирование обосновать можете? Стэктрэйсы наконец завезли, но вам конечно это не нужно. Кто б ещё жисон бы пропихнул это уже давно индустриальный стандарт, но не для с++ очевидно. Хрен с ним хттп, хотя бы юриков бы ещё подвезли, но вам не нужно вы уже говорили что сеть вам не нужна. Почему вы тогда не против путей? 13 лет жили без трэдов и тут на тебе подвезли, зачем?
А теперь посмотрите на стандартные реализации этих штук в Java, Python. Заметили что-то? Правильно, стандартными реализациями никто не пользуется. Нет, ладно, файловые операции в Java - ok, но с какого раза? В чём проблема скачивать дополнительные библиотеки? Я лично не вижу проблем. Но зато вот изменения добавляются в разы быстрее и не проходят все стадии
отрицанияпринятия комитетомстарых пердунов. JSON и прочие свистелки нужны в языках, программы на которых пишутся за 1 минуту, чтобы быстро проверить гипотезу или что-нибудь кустарно автоматизировать и не хочется ради 1 минуты полчаса искать список библиотек для скачивания. С++ не такой язык.
Garykom
05.12.2024 07:36Имхо мы наблюдаем начало заката C++.
В отличие от pure C, который продолжит жить в микроконтроллерах.
А весь этот несовместимый зоопарк С++ подобных уйдет со временем.
Его заменит Rust в массе и частично Go, пусть и потребуются десятки лет.
Но как и Cobol доисторические ошметки legacy на C++ еще долго будут существовать.ahdenchik
05.12.2024 07:36Имхо мы наблюдаем начало заката C++.
Это уже середина, ближе к концу. Началось всё лет 10-15 назад, но очень многие за деревьями не видели леса, да и сейчас ещё не все увидели
В отличие от pure C, который продолжит жить в микроконтроллерах.
Не факт: выпилить его из микроконтроллеров может оказаться даже проще. Как только что-то более безопасное появится, то на него все сразу сбегут - из-за специфики эмбеды в виде ненужности обратной совместимости
Siemargl
05.12.2024 07:36Безопасное то появилось и давно, начиная ещё с Ады. Но мало того, что не сбегают, а даже и не собираются =)
checkpoint
05.12.2024 07:36Скажите, а есть ли какой-то коммитет или рабочая группа в ISO которая работала бы над уменьшением числа фич языка C++ ?
ahdenchik
05.12.2024 07:36Но ведь это сломает священную обратную совместимость
checkpoint
05.12.2024 07:36У меня ничего не сломает. Я и 5% фич не использую. Предлагаю начать урезать осетра.
fen-sei
05.12.2024 07:36Разные люди не используют разные 5%.
А так, если хочется урезать осетра, то имеется С-- (Си с двумя минусами). C--. Первое знакомство
FD4A
05.12.2024 07:36Ну снизу я бы ограничил число лагерей числом областей применения языка. А сверху... Ну умножим оптимистично нижнюю границу на 4.
mbait
05.12.2024 07:36Когда вновь и вновь запускают шарманку про "не ломать ABI в частности и обратную совместимость в целом" у меня один вопрос: кто мешает компаниям зафиксировать версию компилятора и продолжать им компилировать свой
говнокод? Почему с Python 2.7 -> 3.5 этот трюк получился, а с С++ не получится?Mhyhr
05.12.2024 07:36Пример эволюции Python 2 -> 3 без обратной совместимости, создал очень много проблем с пакетами, которых просто не было под 3-ю версию в моменте. Да, было тяжело.
Но в то же время этот переход, параллельно вырастил много молодых (и не очень) разработчиков, которые в итоге переписали всё и неявно унаследовали компетенции по этим проектам от старых мейнтейнеров, которые не готовы были к изменениям в силу разных причин. В итоге большинство библиотек не умерли, а переродились.
Появилось очень много подходов и инструментария, обучающего материала, "свежих" разработчиков, и возможность развивать язык дальше в конце концов. Это похоже на экономику и это не так плохо. Важно грамотное управление проектом (стандартом).
В рядах C++ разработчиков как будто уже накопилась критическая масса, которая готова начать переход. Можно сделать инструментарий для упрощения миграции.
Но пока остается вопрос - куда переходить в случае с С++, что ломать и строить в первую очередь.
kenomimi
Всё это напоминает политику, а не полезное движение в сторону развития. В язык набежали нежные смузихлёбы, которым сложнааа кодить безопасно/эффективно, и начались попытки принести в долгоживущую систему куски раста, го, и прочих короткоживущих хипстерских поделий. Мы все помним, на какой волне был Руби в свое время - и где он сейчас?C++ и так перегружен, и вносить туда всякие сомнительные вещи недопустимо, на текущем этапе здоровый консерватизм наиболее выгодная стратегия развития. Хотите смузячно-хипстерских фич - форкайтесь и пилите свой лунапарк, либо возьмите го/раст...
Невозможно сделать безопасный и эффективный ЯП одновременно. За дефолтную безопасность и защиту от дурака надо дорого платить производительностью. Это фундаментальный закон мироздания, иначе не может быть. Возможность отстрелить себе ногу в C++ это не баг, а фича.
northzen
То, что за дефолтную безопасность надо дорого платить -- самая странная иллюзия людей, которая бы прошла, если бы они хоть чуть интересовались другими языками.
a-tk
Есть два варианта платы: плата временем выполнения в рантайме и плата временем на ублажение компилятора.
equeim
В C++ уже добавили плату в рантайме в виде перезаписи памяти всех локальных и динамических переменных по умолчанию. Также при включении профилей безопасности (пока не в стандарте) будут выполняться проверки индекса в operator[] вектора и прочих контейнеров.
TheDreamsWind
А Вы пробовали скомпилировать на этом "другом языке" кодовую базу схожую по объему с энтерпрайз проектами, написанными на C++? Пару итераций и рабочий день закончен.
И когда Microsoft/Google рапортуют о лучшей производительности разработчиков на "другом языке", мне это видится как "мы ещё не написали на другом языке достаточно кода, чтобы ощутить на себе всю тяжесть защиты от дурака".
Newbilius
.NET (C#) и Java считаются? Видел огромные монолитные проекты из сотен достаточно крупных модулей, холодная компиляция с нуля занимала минут 5-15, но последующие сборки при частичном изменении проекта - от единиц от десятков секунд. Думаю, с такой скоростью сборки можно сделать за день чуть больше пары итераций. Возможно вам не повезло, и вы видели огромные проекты на "других языках", авторы которых просто не смогли правильно настроить инкрементальную сборку?
pavelturch
Ага, на Java проект больше C++. На сях 30 минут собирается, на java 5
f33lg00d
В плюсах во время компиляции можно на шаблонах алгоритм произвольной сложности выполнять, тащемта.
D4nDme
Поддерживаю. К тому же, многие проверки можно делать на этапе компиляции.
Kingas
Если считать, что люди никогда не делают ошибки, что не существует непостоянных багов.
Тут возможно не просто выстрелить себе у ногу, а выстрелить себе в ногу тогда, когда этого ожидаешь меньше всего. Шутливый "Закон" Мёрфи.
Если кому-то нравится копаться в low level г****, то это его право.
Помимо этого есть более важные вещи, как архитектура софта вообще, эффективная утилизация ресурсов вообще. Если говорить про ОС общего назначения... То тут не редко пишут софт в один поток (речь о синхронных вызовах), забывая, что файловая операция это латентная операция с ФС, диском ... и никакие передовые SSD не помогут и не у каждого оно есть. Конечно это не всегда нужно. Например не обязательно для каких-то CLI программ, то там юзер может и подождать. А вот для сервисных программ, которые обслуживают события - это очень даже может быть плохо.
Eclipse2339
расскажите молодому начинающему, что случилось с Ruby в свое время
ivan_mariychuk
А он и не знает, для него просто это была очередная возможность написать про сМуЗи и хИпСтЕрОв.
InfernoSF
Не помню, когда последний раз читал настолько шизофренические набросы, которые еще и получают гору плюсов
domix32
тогда почему консерватизм заключается фразой "ничего не трогаем и тогда ничего не сломается", а все проблемы решить проблемы превращаются в помесь басни "лебедь рак и щука" и ведра крабов.
f33lg00d
Вот не люблю Го, но давайте придерживаться фактов: этому языку уже 15 лет, то есть это примерно как плюсы в 2000 году. Хотя да, тогда плюсы именно и называли короткоживущей поделкой для тех, кто не смог в сишечку.
KanuTaH
Гм-гм, как можно смочь в плюсы, но не смочь в сишечку? Вот обратные примеры есть даже в местных каментах, а о том, о чем вы говорите, я как-то даже не слышал.
f33lg00d
Ну в плюсах есть RAII, умные указатели,
this
в методы как-то сам передается, ещё какой-то там синтаксический сахар, система типов пытается что-то там из себя изобразить... Пример того, что я имею в виду – Линус про C++ и программистов на нем (хотя конкретно этот письмо было и позже 2000, да).Я согласен с тем, что C++ примерно в бесконечное число раз сложнее С, но это предмет для отдельного
сра...обсуждение.ahabreader
Линус о другом писал - 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++"
f33lg00d
Мне кажется, это все из одной оперы: "придумали себе STL какой-то, вместо того чтобы
void*
кастовать, как отцы завещали!"mbait
А на какой волне был Руби? Ценность Руби разве не в Rails? Медленный интерпретатор, monkey-patching, в языке вообще есть что-то ценное?