All streams
Search
Write a publication
Pull to refresh
3
0

Разработчик

Send message
У меня за последний год сложилось ощущение, что в стандартную библиотеку C++ хотят/пытаются внести слишком много функционала.

Был сделан выбор в пользу современных тенденций и требований рынка. C#, Java, Python умеют очень многое из коробки и людям это нравится по мнигим причинам, например:


  • В некоторых компаниях запрещены библиотеки кроме стандартной (нужен variant/flat_set/shared_library? Пиши сам с нуля, в компании <имя практически любой ООО работающей с деньгами> спец требования к безопасности.)
  • Когда пишешь что-то с чем раньше не встречался, хочется использовать что-то идущее вместе с языком, а не выбирать пару дней из N библиотек.
  • Документации на стандартную библиотеку всегда больше чем на сторонние.


Java, project Jigsaw. С точностью до наоборот — распиливание стандартного рантайма на несколько кусков поменьше, для тех кому не надо всё.
Также, никто не тянет Spring, Hibernate, Entity Framework в стандартные библиотеки.
По поводу документации — гораздо легче воспринимать маленькие самодостаточные компоненты.


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

Одна реализация — это адище для разработчика библиотеки и медленное внесение исправлений под ошибки компиляторов. Посмотрите на количество #ifdef/#elif в коде Boost для каких-либо старых компонент… а ведь это при том, что Boost недавно отказался поддерживать некоторые античные компиляторы.



Зато для пользователей библиотеки адищем является целая пачка её разновидностей. А большое кол-во директив условной компиляции — следствие зоопарка компиляторов в прошлом.

>> Lifetimes начисто противоречат как минимум copy by default в C++

> Не вижу противоречий. Поясни?

Может, не совсем правильно выразил свою мысль. Попробую написать более развёрнуто.

Во-первых, тот самый copy by default. В С++ «первичны» именно байтики, составляющие значение, а не само значение, с его семантикой и смысловой нагрузкой. Выражается это в том, что без дополнительных телодвижений значение любого типа будет банально копироваться. Делая «умный указатель», надо не забыть в обязательном порядке или запретить копирование, или правильно его обработать. Как следствие — можно схлопотать implicit copy, после чего дважды уничтожение одного и того же значения. Напротив, в Rust происходит move by default. Т.е. хочешь сделать копию — явно опиши как, а если не нужно — не будет лишних ошибок.

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

В-третьих, тот самый borrowing. А конкретно его сложные случаи, когда заимствованная ссылка попадает внутрь структуры. В Rust в таком случае лайфтайм должен быть явно указан в типе структуры. В С++ как разрешать подобный случай — непонятно.

В-четвёртых, тонны старого кода, который про такие штуки ничего не знает. Считать отсутствие аннотаций ошибкой? Пропускать? Сделать аннотацию «не проверять аннотации»?

В общем, чисто теоретически можно написать для С++ стороннюю утилиту, которая будет выполнять проверки на время жизни. Но геморроя будет слишком много. Просто потому, что система типов С++ проектировалась на максимальную совместимость с С, а значит значения (как я писал выше) там рассматриваются скорее как пачки байт. Как результат — низкоуровневые уши торчат наружу. В то же время в Rust семантика значения первична на уровне с его представлением.

>> к тому же придётся мучительно аннотировать весь код чтобы это работало

> Не мучительнее, чем в Rust.

Компилятор обругает за каждое пропущенное место. Как поступать с пропусками аннотаций в С++ — неясно.

>> Препроцессор останется с нами навсегда во имя совместимости.

> Пусть остаётся. Но пользоваться им будет не обязательно.

Макро-константы. Их валом до сих пор.

>> Аналога же Cargo вообще не предвидится в обозримом будущем.

> Вот уж совсем не проблема языка C++. Cargo не требует стандартизации даже.

Верно. Однако IDE вы, например, хотите. Как инструмент, конечно. Стандартизировать IDE нет никакого смысла. Но почему тогда C++ — фактически единственный язык без вменяемого тулчейна для сборки и доставки зависимостей? Хотя бы как стандарта де-факто?

>> несоместимость С++ ни с кем кроме С++. Такой себе Language lock-in.

> Это утверждение справедливо для любого другого языка программирования.

В принципе да. Конкретно этот мой аргумент наверное несостоятелен. Генератора биндингов из Python в Ruby я не видел :)

>> единственное КМК что держит С++ на плаву — огромное сообщество и гигатонны уже написанного кода

> C++ на данный момент — единственный инструмент, который позволяет эффективно писать производительный код, и причина вовсе не в legacy.

Не совсем. Если не нужно жёсткое «байтоложество», то тот же Golang вполне подходит, несмотря на свой минимализм.

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

Я бы очень даже за. Даже всерьёз начал переделывать один микросервис, просто посмотреть как пойдёт. Остановили генерация биндингов (непонятно что делать с кучей констант, заданных макросами; автора макро-констант убить мало) и zeroing drops — т.е. объект с деструктором распухает, а мне это сильно мешало делать обёртки над хендлами.

Не добавят. Lifetimes начисто противоречат как минимум copy by default в C++, к тому же придётся мучительно аннотировать весь код чтобы это работало. Концепты в Rust есть уже сейчас в виде Traits & Trait impls. Модули добавят хорошо если к 20-му году. Препроцессор останется с нами навсегда во имя совместимости. Аналога же Cargo вообще не предвидится в обозримом будущем.


Короче, единственное КМК что держит С++ на плаву — огромное сообщество и гигатонны уже написанного кода. Плюс несоместимость С++ ни с кем кроме С++. Такой себе Language lock-in.

Для сравнения.
Xiaomi Mi3
родная прошивка на 4.4 — примерно 650-700Мб
родная прошивка на 6.0 — примерно 700Мб
CyanogenMod 13 (Android 6.0) — примерно 300Мб
размеры приведены для архива с прошивкой, с учётом сжатия на флешке будет примерно вдвое больше

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

Получается, когда наступит счастье основные вендоры реализуют поддержку Vulkan, можно будет иметь одну реализацию OpenGL поверх него?

Толщина кода для инита контекста рисования величина б/м постоянная, или по крайней мере всегда отличная от нуля. Дело, думаю, в этом. Как там дела в современном OpenGL — не в курсе, смотрел только мельком.
Vulkan судя по виду и не предназначен для рукопашного кодирования каждый раз. Это скорее «графический ассемблер», как когда-то называли OpenGL. Хотя в такой ситуации OpenGL переходит в лигу «графического Си».
Как Неуловимый Джо :)
Мне кажется, посыл статьи не в том, кто каким флагом машет, а в том, что у поставщиков контента появляется неслабый рычаг «этому плагин даю, этому не даю». Например, лиса и хром получают каждый такой плагин от нетфликса. А потом гугл даёт нетфликсу много денег, и нетфликс отключает все плагины — кроме хрома. Хотите смотреть нетфликс — запускайте хром. Насколько это соответствует реальности — я не знаю, для этого надо смотреть спеку EME.
В лисичке, кстати, проприетарные плагины можно ставить. Более того, они там есть.
К сожалению, именно эта маааленькая особенность превращает использование Gerrit в акт мазохизма, по крайней мере для меня. Настройка локальной копии требует подстановки хука для задания Commit ID, что само по себе немного. Но вот каждый новый чейнджсет превращается в:

— сделать rebase+squash
— обновления делать исключительно amend
— в качестве назначения использовать фиктивный ref, о котором надо помнить
— когда приходит добрый сосед и мержится, надо ручками опять делать ребэйз

Короче, мне это сильно напоминает старые добрые времена SVN по количеству рукопашной работы.
Кто-нибудь в курсе, это полноценный нативный клиент?
Или приблуда вроде Slack Client, который по факту запускает WebKit?
Попробую перечислить конкретно то, что раздражало меня. Телеметрию и т.п. не беру, слишком субъективно

1. Обновления ставятся когда МСу удобно, а не мне. Лечится правкой в реестре. Пока что.

2. Пачка лично мне не нужных приложений типа OneNote, Cortana, которые или не выпиливаются вообще, или радостно возвращаются после первого же апдейта. Даже если выпилить весь пакет вместе с ярлыком с помощью PowerShell

3. Пачка «системных» сервисов типа Content Delivery Manager, которые тоже не поддаются никакому управлению, включаются в произвольное время (что само по себе не проблема) и адски выжирают CPU и память. Рекомый CDM у меня так себя и вёл.

Ну и ещё какие-то мелочи, из разряда «проблемы индейцев шерифа не волнуют».
Плюс Win 10 по-прежнему имеет тенденцию жрать место на диске за счёт WinSxS. Сделать к нему нормальный dependency management МС в своё время не удосужились.
До 7-ки включительно windows была удобна и простому пользователю, и продвинутому. Начиная с 8-ки возможности продвинутой настройки стали усиленно прятать или перетряхивать, «оказуаливая» систему. 10-ка просто стала финальной точкой в этом процессе. Т.е. 10-ка — хорошая, наверное, система для офисных ПК. Может для геймеров. Но для тех, кто привык контроллировать поведение своего ПК она стала занозой в заднице. Именно из-за политики «большому дяде лучше знать». Я, помнится, обновился ещё в августе прошлого года, в самом начале щедрого предложения. А уже в начале октября с матюгами пересел на Linux Mint. Просто понял, что систему я больше не контроллирую никак. И любые попытки такого контроля с моей стороны будут выпилены следующим же апдейтом.
Мне кажется, или у таких концептов слишком много точек отказа? Одна только перемещаемая активная броня чего стоит.
Rust
Там собсно сделали отслеживание владения и алиасинга компилятором. От зацикленных умных указателей конечно не спасает на 100%, но ногу себе отстрелить гораздо труднее.
Cinnamon, зона ресайза явно больше одного пикселя. Только что проверил.
Мой личный опыт показывает, что это все окружающие призваны работать с С++ через C ABI. С++ не стыкуется сам по себе ни с кем кроме С и С++. Все остальные делают C-compatible FFI. А пакетный менеджер не родился КМК из-за того, что производителей компиляторов было несколько. И они в начале развития С++ не очень хорошо дружили друг с другом. Посмотрите хотя бы на «зоопарк» систем сборки. Отсюда, кстати, и отсутствие какого-то единого соглашения на структуру исходников для каждого «компонента». Другие языки появлялись усилиями какой-то одной компании или группы энтузиастов, и только потом могли появляться «форки». Либо просто выходил порт референсного компилятора/рантайма.
Как по мне, двоеточие визуально отделяет имя параметра от его типа, что есть хорошо. Если вы ссылаетесь на golang, то там для такого различения требуется немного «приморгаться».
int[] и любой вэлью-тип с Вами не согласен. Будет реф на ячейку в массиве.

Information

Rating
Does not participate
Location
Украина
Registered
Activity