Comments 1190
Однако от признаных экспертов я ожидаю взвешенного освещения ситуации, которое, как минимум, не содержит грубых фактических ошибок

И напрасно.
Эксперты — они потому и эксперты, что узкая специализация.
Чем больше времени потрачено на что-то одно, тем меньше его на всё остальное.
Чем больше набито шишек, тем больше предубеждение, что «там» всё еще хуже и нежелание набивать их еще раз. Всяк кулик своё болото хвалит.

В качестве канонічного примера можно почитать спичи Линуса о C++.
Есть такая штука, называется эффект Даннинга Крюгера. И смысл у него в том, что чем больше человек знает, тем более осторожны его суждения в своей и особенно в смежных областях. Хвалить свое болото и быть некомпетентным в чужом — это несколько разные вещи. Линус топит плюсы не потому что они плохи сами по себе, а потому что их пытаются регулярно пихать в ядро, где, по его месту, им не место.

Я так понял, что Роман выступает не «за» или «против» а за профессионализм и за научный подход.

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

Другое дело, что он явно не хочет с этим заморачиваться.
Не то, что «не хочет». Он «не может».

Подавляющий по объёму (но, конечно, не по важности) объём кода Linux написан людьми, которые имеют слабое представление о C и C++ в прицнипе — они вообще железячники, из просто драйвера нужны, чтобы железяку продать.

Когда они карго-култят драйвер дёргая куски C кода — результат получается слегка вменяемым и его можно, итерационно, довести до чего-то разумного.

Когда они чего-то напишут с полным игнорированием Style Guide на C++ — это можно будет только выкинуть и переписать с нуля. Кто будет это делать?

Очень сильное заявление, особенно, что люди имеют слабое представление о Си. Пример, приведёте из кода?

Memory leak в драйвере megaraid. Могли быть устранены в зародыше — при внимательном и вдумчивом написании кода. Либо прогоне kmemleak на рабочей системе. Пришлось патчить самому

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


P/S. Я не согласен с утверждением: «людьм, которые имеют слабое представление о Си»Я даже не спорю о их представлениях о С++ или rust или python.

Погодите. Вы просили пример. Я привел. Если бы разработчики этого конкретного драйвера были чуточку "умнее среднего" — проблемы не было. Но она есть. Никаких обобщений я не делал. Вы меня с кем-то перепутали

Нет, возможно я вас ввёл в заблуждение, но я просил пример не понимания Си. Не баг, а именно не понимание Си.

баг — это следствие (развожу руками):


Если бы разработчики этого конкретного драйвера были чуточку "умнее среднего" — проблемы не было

и они писали бы корректный код (не синтаксически, а логически)

Посмотрите на реакцию на любой vendor-драйвер в LKML. Из последнего — дискуссию про exFAT от Samsung можете посмотреть.

Т.е вы мне предлагаете посмотреть дискуссию, где обсуждаются конкретные проблемы драйвера exfat. Но при этом утверждаете, что люди не понимают в Си?

Потому что когда по неизвестно какому разу обсуждается что нельзя проверять на переполнение с помощью проверки x + 100 < x — то это оно и есть.
почему? Для беззнаковых чисел именно так и можно проверять (если тип не будет расширен до int с unsigned char)
И это тоже нехорошо: получается, что беззнаковая арифметика хуже оптимизируется, чем знаковая, по причине тараканов 40-летней давности.
Ну вот если бы там речь шла только про беззнаковые числа — вопросов бы не было.
И смысл у него в том, что чем больше человек знает, тем более осторожны его суждения в своей и особенно в смежных областях
Нет, всё вообще не так. Оригинальное исследование не утверждает того, чего ему приписывают.

Начнём с того, что мужика звали не «Даннинг-Крюгер». Это два разных исследователя, их фамилии пишутся через тире с пробелами: «эффект Даннинга — Крюгера».

Оригинальное исследование 1999 года заключалось в следующем: студентам раздали опросники на разные темы. Также студенты оценили, насколько хорошо они ответили.

Студентов разбили на квартили по успешности ответов. Получилось что-то такое:



То есть всё полностью наоборот: чем лучше себя человек оценивал, тем лучше он себя проявил. При этом в среднем первая квартиль пусть и отвечала хуже второй, но оценила себя ниже, вторая — хуже третьей, но и оценила себя ниже третьей, и так далее.

Да, первая, квартиль отвечала куда хуже, чем ожидала сама. Но это не даёт право в Интернете затыкать рты всем, демонстрирующим уверенность в чём-либо: «У вас Даннинг-Крюгер, азаза».

Само исследование невнятное: какие-то статистические выкладки с регрессией к среднему. Выше был дан график для опросника по юмору. График для опросника по логике выглядит более непонятно:



Каких-то больших различий нет: 5—10 процентов. При этом хорошо себя оценили как те, кто плохо ответил, так и лучшие. Получается, что если человек в себе уверен, то это либо профан, либо эксперт?

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

В 2006 году исследование повторяли. Результаты совсем невнятные. Люди себя оценивают хуже, если тест был сложный?



Нет никаких эффектов. Если вы с кем-то не согласны, то нужно опровергать чужую точку зрения.

Rust убьёт C++ и, возможно, C в перспективе 10 лет, это уже просматривается сейчас. Даже если Rust проигрывает в каких-то микробенчмарках, это ничего не значит. Миру слишком давно нужен такой язык как Rust, с богатыми. типами, с ручной, но безопасной памятью, с системой пакетов/библиотек, близкий к железу. Единственное, что может помешать Rust, это появление аналогичного по характеристикам языка, с поддержкой от крупного вендора, с более простой семантикой управления памятью.

А зачем кому-то переписывать мегатонны существующего кода? Вот в один день бизнес примет решение: мы писали свой софт 10 лет на c++, а давайте потратим ещё 10 лет на переписывание на другой язык, чтобы через 10 лет получить тот же функционал, что у нас есть сегодня, но собирающийся из другого языка.
Давайте будем немного реалистами.
Язык хороший. В своей ниже отличный. Но переписывать на него legacy — кому это надо и чем это в деньгах выгодно?

По-моему, можно «убить» C++ просто начиная новые проекты на Rust, а старые библиотеки оборачивая в безопасный код. Ну и переписывая в них самые проблемные места, возможно
Чтобы избежать будущих CVE репортов. Если legacy кодом никто не пользуется, то можно и не переписывать. Если же это популярный проект, который периодически все еще создает проблемы с багами и безопасностью, то вполне можно. Теже ядра операционок и драйвера — переписать их на Rust очень даже надо.
Зачем переписывать уже давно работающий код? Кто за это будет платить? Зачем переписывать на новый ЯП и при этом при переписи возможно посадить новую багу (да, это будет не бага памяти, а перепутанный < с >). Уже где-то была ссылка на то, что при переписывании куска Firefox на Rust они допустили ту же багу, что когда-то N лет назад была пофикшена в старом коде. Это ни разу не камень в огород Rust (он то здесь точно не виноват). Это всё проблемы переписывания кода с нуля.

Хотите действительно безопасности? Тогда пропагандируйте Idris/Agda/Coq и DeepSpec. Но все мы живём в реальном мире и понимаем, что это на данном этапе развития невозможно :)
Платить за это будет компания, которой надоело CVE репорты фиксить в своих продуктах. Возьмем какой-нить интел или броадком. В их драйверах тонны уязвимостей находят и большинство так или иначе связаны с ошибками работы с памятью (из последних вон классический выход за границы при парсинге пакетов). Имеет смысл переписать это на языке, который предоставит гарантии защиты от таких ошибок? Я думаю имеет. Уж тем более имеет для потребителей, которые получат продукт выше качеством.

Вообще любой продукт, от которого зависит пол мира, очень даже имеет смысл переписать. OpenSSL приводят часто как хороший пример. Был бы он на расте мы, как минимум, избежали бы пачки уязвимостей, которые поставили эти пол мира на уши. Имеет смысл? Я думаю да.

И это не пропаганда раста, на котором я даже не пишу. Это просто здравый смысл. Нужно использовать лучший инструмент там, где это важно. Какой-нить игровой движок переписывать на раст? Там это не важно. Драйвер сетевой карты? Очень важно.
А я считаю, что процесс должен быть итеративен, а не «взять и переписать на совершенно чуждую технологию». А итеративное переписывание в случае Rust получается, только если на либы разбивать.

Я бы предпочёл переписывание на С++, на котором также ошибки подобного уровня не допускаются. Не хочешь переполнений — используй арифметику без UB на переполнениях. Не хочешь отрыва конечностей при работе с памятью — без проблем, просто не работай с сырой памятью. Не получается? Оберни в безопасные с как можно более низким оверхедом обёртки.

И да, Rust достаточных гарантий не предоставляет. Например, многопоточка. Посмотрите, что происходит при двойном локе мьютекса (происходит unspecified behaviour. А что это такое на самом деле — вы инфы, кроме предположений на гитхабе, не найдёте).
Не хочешь переполнений — используй арифметику без UB на переполнениях.
И где вы в C++ нашли «арифметику без UB на переполнениях»? Или вы при -trapv? Так он во-первых не работает в GCC уже больше 10 лет, а во-вторых при попытке включить его для уже существующего кода в Clang тот начинает «сыпаться». Потому что оказывается что там реально происходят переполнения, просто результат работа никем не используется и потому «всем пофиг».

Каждую строчку перепроверить и убедиться что там всё хорошо? Так в этом случае уже и на Rust можно перевести всё.

Посмотрите, что происходит при двойном локе мьютекса
А что для таких случаев предоставляет C++?
И где вы в C++ нашли «арифметику без UB на переполнениях»? Или вы при -trapv?

Не, я про обычные вещи уровня safe_int
А что для таких случаев предоставляет C++?

Ровно то же самое, что и Rust. Чёрт пойми что.
Ровно то же самое, что и Rust. Чёрт пойми что.

Не совсем. Гарантируется, что функция не вернёт после второго лока:


However, this function will not return on the second call (it might panic or deadlock, for example).

Тут скорее platform specific behaviour, которое для большинства популярных платформ означает deadlock, что не нарушает гарантий Раста (т.е. memory safety и отсутствие data races).

Меня не это смущает. А то, что они ссылаются на unspecified behaviour, описания которого нет. Вот и все мои претензии. Описание, которое есть на гитхабе, ещё не является финальным.
UB — по определению не может быть описан. Он на то и unspecified.
Сорян, unspecified behavior — по определению может быть не описан. Как же бесит в С++ вот эта необходимость всегда быть начеку.
Но что такое unspecified — должно быть описано. Зачем-то же С++ в Стандарте описывает, что это такое.

А можно небольшую просьбу от человека, знакомого с C, Rust, но плюсы знающего исключительно на уровне "Си с классами"?


В дискуссиях "C++ vs Rust" регулярно используется довод, что в C++ можно делать всё не менее безопасно, чем на Rust, и наверняка хорошо известно, что именно для этого требуется. Скорее всего, и компиляторы / линтеры это должны уметь.


Не могли бы вы (в значении "эксперты по языку C++", не обязательно лично Вы) показать пример конфигурации открытого компилятора и/или открытых линтеров, обеспечивающих адекватную степень безопасности? Чтобы была возможность начать проект на C++, включить их в этой конфигурации и быть уверенным, что они дадут мне по рукам, когда я случайно использую malloc вместо make_unique / напишу код с ошибкой инвалидации итератора / сделаю какую-нибудь ещё глупость, про которую я просто не в курсе. Потому что за себя я уверен, что даже если я прочитаю от корки до корки C++ Core Guidelines, как минимум поначалу такие ошибки всё равно будут.


Вот, например, clang-tidy --checks=cppcoreguidelines-*,modernize-* — это адекватно, избыточно или недостаточно?

Этого всегда будет недостаточно. Такие проверки в принципе неразрешимы, придётся банить потенциально корректный код (подход Раста как раз). А те, что разрешимы требуют много ресурсов, что делает их нерентабельными (замедлять компиляцию 99.999% корректного кода ради того чтоб найти ошибку в 0.001% мало кто хочет).

Так в том-то и дело, что меня вполне устроит в качестве ответа линтер, который банит потенциально корректный код. Если он скажет "написанный так код потенциально опасен, так нельзя, пользуйтесь абстракцией такой-то" — оно и к лучшему. Если мне действительно будет нужно — найду в документации, как разрешить данное конкретное нарушение правил линтера (а заодно прочитаю, чем именно оно опасно, на что именно нужно проверить код вручную и о чём нужно предупредить комментарием следующего разработчика).


Не устраивает меня ситуация, в которой "разумеется, C++ позволяет всё это безопасно написать, но чтобы быть уверенным хотя бы на 90% в безопасности написанного, обязательно необходим ревьюер с опытом в современном C++ от N лет". Новые проекты в опенсорсе нередко начинаются с одного человека (или маленькой команды), и я не понимаю, как сейчас начать проект на современном C++ без хождения по всем стандартным граблям с нуля.

Из переписки (прошу прощения за лексику):
[Forwarded from Denis]
блин, нашёл тут на работе в своём старом коде
std::vector<_> vec = ...;
auto it = vec.begin(), end = vec.end();
while (it != end) {
    if (/* some conditions on `it` */) {
        ++it;
        continue;
    } else {
        // ...
        it = vec.erase(it);
    }
}

[Forwarded from Denis]
это просто п**дец, как я мог так ошибиться

[Forwarded from Denis]
переписал в иммутабильном стиле, планирую грепнуть и всё нафиг переписать так

[Forwarded from Stanislav Popov]
а в чем проблема?

[Forwarded from Denis]
vec.erase(it) инвалидирует все итераторы, которые распологались «после» it, в том числе и vec.end()

[Forwarded from Denis]
а я его закэшировал какого-то хрена

[Forwarded from Denis]
еб*чие плюсы, и ни один сраный линтер из тех, что мы юзаем, не заметил х**ни :(

[Forwarded from Denis]
у меня щас горит на самом деле, потому что ни clang'овский scan-build, ни cppcheck не находят говна

[Forwarded from Denis]
придётся видимо грепать проект по .erase(

[Forwarded from Denis]
плюсы — дно

[Forwarded from Denis]
даже когда вроде вот знаешь всё х**ню и умеешь их готовить

[Forwarded from Denis]
на секунду отвлёкся/забылся — проиграл
Собственно эта дискуссия показывает — почему Rust-сообщество так резко реагирует на «экспорт небезопаности».

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

И тогда зачем весь этот «цирк с конями»? Один такой язык у нас уже есть…
Так в расте то при этом будет явно виден небезопастный код, а в с/с++ как я уже приводил пример в трех безобидных строчках UB можно схватить.
Посмотрите на историю с Actix. Там функция, не помечанная unsafe, даёт доступ к внутренностям без проверок. Вот после этого можно и в rust «в трех безобидных строчках UB можно схватить».

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

Именно после этого — можно утверждать, что в Rust — всё на порядок проще с этим. Потому что небезразличный человек, буквально со стороны, — пробежался по ансейфам и нашёл этот баг.
Люди совершают ошибки. Это не случайность, это — норма.
Rust — язык созданный для упрощения борьбы с ошибками и в этом вся его прелесть. Хотя компилятор по прежнему не может думать за человека, но довольно таки большую часть работы он с человека снимает. Остаётся выполнить свою часть.

Фишка в том, что в расте такой код "за забором". И я как-то считал, в СТД (в котором ужас-ужас сколько ансейфа) его значение порядка 0.1% от общей кодовой базы (считал очень грубо, по строчкам). Это значит, что у вас не миллион строк кода где можно "на секунду отвлечь/забыться", а тысяча. А теперь допустим что программист в среднем "забывает/отвлекается" раз на тысячу строк кода. В итоге в одной программе будет тысяча багов из-за этого, а в другой — один.




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

Фишка в том, что в расте такой код «за забором».
Когда он за забором, то всё в порядке. А когда у вас вот такое вот:
pub(crate) fn get_mut(&mut self) -> &mut T {
 unsafe { &mut *self.inner.as_ref().get() }
}


Это реальный код, из реального проекта.

Такими методами я вам могу в любом проекте достичь ультрабезопасности: будет у меня всего две unsafe функции. peek и poke. Каждая в одну строку. И всё. Всё остальное — «офигеть как безопасно».

Если на этом проекте был хотя бы 1 ревьювер этот код бы не прошел ревью.


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

Такими темпами я могу вам в любом коде любую хрень сделать: bool тип в сишарпе которые не true и не false, монаду в хаскелле которая не монада, и всё остальное. Если вы написали unsafe и нагородили ерунды, то это вы виноваты, а не язык.


И да, то что в огромном проекте как актикс смогли за полчаса найти все места которые могут вызывать УБ это и есть польза от этого unsafe.

Кстати, два момента


  1. с этой функцией нет проблем, потому что из &mut self можно возвращать &mut на дочерние элементы
  2. если её нарочно сломать (например, вместо &mut self использовать &self), то мири скажет, что код невалидный и починили бы вы свои ансейфы, дорогие товрищи:

image

Посмотрите здесь. UnsafeCell используется вроде бы правильно, но прикол в том что там оно завёрнуто в Rc, и нарушается контракт Rc!


Кароче уб в расте такое же не очевидное как и в плюсах


Вот плейграунд c демонстрацией. Я скопировал весь код из actix/cell.rs, чтобы показать уб


Кстати miri ловит, но естественно только при использовании. Т.е. сама библиотека для мири выглядит вполне ок, а вот её использование через сейф апи приводит к уб (которое мири ловит).

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


Кароче уб в расте такое же не очевидное как и в плюсах

Не совсем — мне неизвестен тул, который ловит УБ в плюсах. Есть всякие санитайзеры, но они такие, ненадёжные товарищи. А если закинуть этот код в MIRI то можно получить замечание от машины:


error: Undefined Behavior: trying to reborrow for SharedReadWrite, but parent tag <4320> does not have an appropriate item in the borrow stack
  --> src/main.rs:50:5
   |
50 |     v1.push(4);   //v2 mutated through v1
   |     ^^ trying to reborrow for SharedReadWrite, but parent tag <4320> does not have an appropriate item in the borrow stack
   |

Впрочем, я сторонник не писать unsafe вообще и дать это на откуп популярным библиотекам и std.


Кстати miri ловит, но естественно только при использовании. Т.е. сама библиотека для мири выглядит вполне ок, а вот её использование через сейф апи приводит к уб (которое мири ловит).

Не так, скороее МИРИ это интерпретатор который ловит уб который происходит. То есть оно может найти УБ если оно триггерится где-то в программе, но оно не найдет потенциальное УБ которое не эксплуатируется. Ситуация похожа с тестами.

Я думаю, что проблема с актикс следующая:
У чела в голове было полуинтуитивное понимание того как это работает и почему оно сейф (оказалось в итоге не полностью правильным). Ему нужно было напрототипировать производителый веб сервер, а доказывать все компилятору лень. Выносить ансейф вверх по стеку в публичное апи, тоже не хочется. В итоге получаем такой говнокод (по меркам раста) как приведен в комментарии выше. Не все же такие фанатики как уважаемый 0xd34df00d, которые пишут доказательство корректности gcd на 200 строк.

Просто зачем писать на языке вещи, для которых он подходит слабо, и которые в нём выражаются неидиоматично?


Неохота ничего доказывать — не берёте раст (или идрис), а берёте С (или хаскель) и решаете задачу. В чём смысл писать сервер на расте с кучей ансейфа (сортировку на идрисе с кучей believe_me) — просто чтобы сказать, «я написал на расте сервер» («я написал на идрисе сортировку»)?


Тем более, если FFI околобесплатный.

как мне кажется, это называется — преждевременная оптимизация. которая корень всех зол.
и камень в огород с++ => если бы компиляторы умели сами когда можно кешировать .end(), .size() и прочее — никому бы в голову не пришло руками выносить их из цикла. а так — после того как вынос i< vec.size() ускоряет цикл и позволяет его векторизовать — начинаешь на автомате везде это делать. ну и провтыкиваешь в вышеприведенном случае.

Забавно, но в данном случае виновата как раз недооптимизация. Если бы алгоритм был выбран не квадратичный, а линейный — ошибки бы не было...

ну а как вы линейно это сделаете? пробежаться по вектору — пометить ненужное и переписать в выходной вектор? памяти *2 как минимум. плюс может быть что кейс с erase() редкий и в хвосте, а так — весь массив переписывать.

Надо просто бежать двумя итераторами, а не одним:


auto i = vec.begin(), j = vec.begin(), end = vec.end();
for (; j != end; ++j) {
    if (/* some conditions on `j` */) {
        if (i != j) *i = std::move(*j); // или swap
        ++i;
        continue;
    } else {
        // ...
    }
}
vec.erase(i, end);

Как-то так, если я ничего не напутал.

Примерно такая идея, только пишется она так:
vec.erase(std::remove_if(vec.begin(), vec.end(), [](auto&& j) { /* ... */}), vec.end());

[и ниже это уже написано, оказывается]
В С++ хватает подводных камней, но данный пример к ним не относится. Т.к. его можно было избежать, зная устройство вектора. Первый же пример задачек Герба Саттера говорит про инвалидацию итераторов вектора. К тому же следовало использовать лист, если изменение контейнера происходит постоянно. Либо переписать данный кусок с использованием remove и потом в конце вызвать erase

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

Tmad PsyHaSTe я нормальный и здоровый человек. Я не хочу думать о том, где мне компилятор С++ подсунет очередную жирную свинью. Я хочу сконцентрироваться на решении бизнес задачи. Тупо. Дешево. Сердито. Надежно. Без этих выкрутасов. Пускай меня компилятор страхует от ошибок. А не тупо молчит как партизан.


Помню, я купил книжку про умные указатели и всю дичь, что с ними вытворяли . Это был далекий 2000. Я просто тащился с того, что эти ребята с Саттером, Александреску творили. Но тащить это в прод. За ради чего ?

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

В Rust две мутабельные (исключительные) ссылки на одно и то же — не могут быть валидным кодом. И попытка их создать — это всегда UB. Поэтому нет смысла и в ослаблении ошибки до предупреждения.

Тогда, получается, невозможность присвоить строку целочисленной переменной — это проблема С++? Это же совершенно валидный код, только не компилируется :-)

В С++ можно присвоить строку целочисленной переменной, если определить соответствующее неявное преобразование. Практика, конечно, так себе, но есть методы и функции, которые не дают какого-то значного оверхеда в плане удобства. А Rust со своим ограничением на мутабельные ссылки будто бы не предлагает пристегнуть ремень, а требует замотаться в поролон и залезть в ёмкость с каким-нибудь гелем. Я всеми руками за безопасность, но имхо это — перебор.

Ну так и в расте можно — если сделать дереф в какой-нибудь Rc, и практика тоже так себе.


Я всеми руками за безопасность, но имхо это — перебор.

Во-первых нужно понять что &mut это не "мутабельный", а уникальный. Да, надо было изначально нормально назвать, были пропозалы чтобы это переделать, но оставили как есть в угоду обратной совместимости. По понятным причинам, уникальная ссылка должна быть уникальной.


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

> Ну так и в расте можно — если сделать дереф в какой-нибудь Rc, и практика тоже так себе.

Я просто хочу получить ссылку, а не использовать новые абстракции.

> Во-первых нужно понять что &mut это не «мутабельный», а уникальный.

И что даст это понимание?

> В хаскелле вон вообще никакой мутабельности нет

Хаскелль — функциональщина со сборщиком мусора. Rust же претендует на другую нишу.

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

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

В Rust тоже можно так сделать через явные преобразования. Напишите мне код на C++, дам вам код на Rust.

То есть вы предпочтёте иметь в своей программе возможность обратиться к разделяемой переменной из разных, не захватив при этом предварительно блокировку? Ну ок.

Вы имели в виду из разных потоков? Да, бывает и такое. Переменная может быть синхронизирована другими способами, или обращение к ней происходит только специальным образом, который гарантирует защиту от гонки.

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

Ага, все они завязаны на блокировке, если тип данных не атомарный. У меня, к примеру, написанный lock-free контейнер, обращение к которому не требует синхронизации. Или же умный планировщик, который даёт соотстветствующие гарантии. Зачем мне эти ваши абстракции?
Это абстракция, которая мне нужна. Зачем мне к ней добавлять ещё Rc<RefCell<...> >, к примеру?

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

Знаете, я даже не знаю: троллинг это или стёб. У нас в проекте тоже есть пара lock-free контейнеров. Так там на каждую строчку несколько часов убито консультаций с мануалами и специалистами по архитектуре процессоров, чтобы быть уверенными в том, что там ни компилятор, ни железка нам ничего не испортят (если вы читали соотвествующую статью, то знаете, что математически правильный lock-free алгоритм без соотвествующих барьеров = испорченные данные). Вбухав в небольшой кусок кода такие ресурсы уж навесить несколько дополнительных пометок для компилятора — точно не проблема.
Кейс, описанный в этой статье — единственный тип реордера, который может произойти на x86. У Вас найдется реальный код, в котором этот реордер создает проблемы?
Centimo, на мой взгляд, указывал на то, что в случае lock-free программирования подстроиться под гарантии Rust'а не получится — придется все писать на unsafe'е. Но это всего лишь моя интерпретация, конечно.

Вы не правы. Вот например https://github.com/xacrimon/dashmap отличный пример как lock-free структура данных спокойно живет с гарантиями Rust. Реализовано это через внутренюю мутабельность и имея immutable ссылку на непосредственно словарь (обычно разделяемую через Arc) можно удобно обращаться к ней из многих потоков. Понятно что внутри реализации есть определенный процент магии атомик переменных и страшных вещей, но при этом внешний интерфейс простой и удобный для прикладного программиста

Я понимаю что внешний интерфейс будет нормальным, но внутреннюю реализацию Rust никак не защитит. Но да, «все писать на unsafe'е» — прозвучало слишком сильно.
с гарантиями Rust
с типичными гарантиями, я бы сказал =)
github.com/xacrimon/dashmap/blob/master/src/iter.rs:238
unsafe {
                        let k = util::change_lifetime_const(k);
                        let v = &mut *v.as_ptr();
                        return Some(RefMutMulti::new(guard, k, v));
                    }
...
            let mut guard = unsafe { self.map._yield_write_shard(self.shard_i) };
            let sref: &mut HashMap<K, V, S> = unsafe { util::change_lifetime_mut(&mut *guard) };
Ну так и пишите на C и не морочьте голову ни себе, ни тем, кто знает, зачем и почему в Rust есть запрет на существование двух мутабельных ссылок сразу)
Извините, но человек, который это написал, ещё не до конца научился готовить С++. Меня в три часа ночи разбуди — не поднимется рука так написать. Я уже молчу, что специально для этого же есть std::remove_if и remove-erase idiom, зачем вообще писать так сложно и с ошибками этот код, который делается в одну строчку на стандартных алгоритмах из ???
vec.erase(std::remove_if(vec.begin(), vec.end(), [](auto&& item){return !some_condition(item);}), v.end());

Я ещё в свою библиотеку велосипедов-обёрток над std добавил шаблон remove_if(container, predicate), чтоб не писать begin()/end() (и не писать end() два раза). Думаю, с появлением концептов и рейнджей в С++ это будет так же легко делаться из коробки, без обёрток.

Ага, абсолютно логичный и понятный синтаксис. Понятно, что это устойчивая remove-erase idiom, но она все равно очень многословна. Что мешало в стандартную библиотеку добавить такой вариант:


std::remove_if(vec, [](auto&& item) { return !some_condition(item); });
Не знаю, полностью согласен, что это странно, поэтому написал эту обёртку сам. Но с появлением ranges в С++20 это должно быть решено из коробки.
Видимо такой конфигурации мы не дождемся. Я вот тоже хочу C++ еще раз попробовать, т.к. в геймдеве все еще везде C++, но как-то проводить дни в дебаггере за поисками глупых багов совсем не хочется. С растом я дебаггер еще ни разу не запускал.
Если кода писать на С++ больше намного, чем на Rust, то конечно дебаггер открывать не будете :) Я вот в С++ тоже дебаггер давно не открывал. Выборка не очень репрезентативна, скажем так :)
Я пишу в основном на плюсах, иногда делаю ошибки (как известно, без ошибок пишет только Торвальдс), и довольно часто приходится их искать с дебагером. ЧЯДНТ?
А мне на JS дебаггером приходится пользоваться, ЧЯДНТ? :) Может, если я перестану писать на плюсах, это как-то поможет? :)

Всегда вопрос в системе типов. Чем она мощнее, тем меньше нужда в дебаггере, но тем лучше нужно читать, что за ошибку компилятор пишет. У меня например до сих пор ошибки в хаскель коде иногда вызывают оторопь — непонятно, что не так. Хуже, чем дебажить то, что если ошибка непонятна то просто "пройтись по строчкам и сравнить ожидаемое поведение с реальным" нельзя. Из плюсов — вы доказываете работоспособность в общем случае, а не тот сценарий который протыкан. Ну и навык понимать ошибки компиляции и избегать частых проблем — нарабатывается, а дебажить меньше не приходится. Встречал в хаскель чате людей, которые много лет в прод на нём пишут, а дебажиться не умеют вообще, не слышали про watch window и вот это всё. Забавно, но факт.

Встречал в хаскель чате людей, которые много лет в прод на нём пишут, а дебажиться не умеют вообще, не слышали про watch window и вот это всё.

Моя история.


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

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

Проблем я вижу две


  1. Переписывание на Rust не убережет от логических ошибок
  2. Железо тоже имеет тенденцию подводить. Rust не поможет от того, что благодаря сбою на аппаратном уровне случится флип бита. А между прочим такое случается реально постоянно.

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

Так кто-то же должен написать программу, что бережёт её от ошибок. Сколько там сейчас программистов на Idris? :)

Ошибки в пруфе быть не может, идрис (и подобные языки) как раз от них и защищает. Ошибка может быть в доказываемом утверждении (в спеке, иными словами), но это уже совсем другой разговор.

Ну тогда правильнее сказать «идрис не спасёт от ошибок в понимании заказчика». Но тут ничего не спасёт.


А от ошибки в спеке, кстати, тоже может спасти. Ближайший пример — нахождение наибольшего общего делителя, который тут уже упоминали. Я сначала написал тип соответствующей функции как (m, n : Nat) -> (d ** Gcd d m n) — то есть, для двух натуральных чисел m, n возвращается какое-то число и доказательство того, что оно НОД. Сел доказывать, доказываю, доказываю — упёрся в то, что кусок не могу доказать. А причина-то простая: хотя бы одно из чисел должно быть строго положительным, иначе НОД не определён, и я в процессе доказательства об это споткнулся. Поправил тип — всё доказалось.

Вы не поверите, но Idris тоже не защищает от логических ошибок. Потому что лигическая ошибка — это несоотвествие кода требованиям заказчика. А чего заказчик хочет — часто и он сам не знает и в спецификации неправильно пишет.

Ворнинги компилятора тоже не спасут от всех ошибок, поэтому включать их не надо?

Так наоборот — максимальный уровень verbosity компилятора, а еще лучше — обработка ворнингов как ошибок компиляции и пускай разработчик дорабатывает )

Только не решили проблему компиляции с++ кода часами и отжора компиляторов всех ресурсов системы )))))

Только вот она решена отчасти с помощью C++20 модулей. Отчасти потому что кеша инстанциаций в компиляторах нет. Был когда-то проект кеширующего компилятора на базе Clang, но он помер, к сожалению. Zappcc емнип.

Ну если в плюсах еще докидать тонну атрибутов для лайфтайм ворнингов, а потом все это объявить ошибками при помощи флагов компиляции, то да, один из источников UB мы устраним :) Останется еще 1023)

Простите, а как выглядит код на каком угодно языке, который защищает от флипа бита? Я думал, даже в космосе обходятся тем, что сравнивают два вычисления в железке и чуть что перезагружают вообще всё.
Ну я бы всё таки не путал флип бита и банальную инвалидацию итератора. Вероятность возникновения такого кажется немного разной :)

Ну да, одиночные сбои я на работе регулярно наблюдаю, иногда даже большими пачками, а инвалидацию итератора никогда не видел :)


(Не пишу на C++ и занимаюсь испытаниями на радиационную стойкость. В коде на Rust почему‐то инвалидации не происходит, в коде на LabVIEW, C и ассемблере тоже…)

За 10 лет продакшн работы я встречал наверное тысячи баги, из которых ноль связанных с железом. По-вашему, стоит забить всё же на техники, уменьшающие баги в софте, ведь железо все равно глючит?

Вы сделали неправильный вывод ) баги в железе — это объективная реальность. Вот недавно была статье на Хабре, где рассказывались разные кейсы. Например, при передаче по сети бьётся бит и запрос уходит на другой домен, отличающийся одним символом. Или при чтении с диска. Или в памяти. В половине случаев — это все решается валидацией параметров. Немного помогают контрольные суммы.
В общем, это все не означает, что Раст плохой язык, но беда может прийти оттуда, откуда не ждёшь )

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

Да всё, что угодно бывает. У меня знакомые из крупной конторы рассказывали, что Intel им как-то поставил «особо быстрые» CPU… в которых неправильно работало деление. Там итеративный алгоритм, на высокой частоте происходили «гонки»… в результате ответ, иногда, на единичку отличался от нужного, а остаток, сволочь такая, оказывался больше делителя. Конечно hashmap на это отреагировал… не вполне адекватно.

Но пока у вас на 100 (а то и 1000) багов в софте случается один такой аппаратный баг… нужно фиксить софт. А с железом потом уже бороться. Когда в софте не будет столько «косяков».

P.S. В том случае, кстати, софт фиксить не стали. Написали прогу, которая за день прогона определяет — есть бага в CPU или нет и если бага в наличии — выключает Turbo. Ну а потом эти процы по гарантии поменяли.

Вы только что своими словами пересказали историю fdiv bug'а из pentium. Первых которых. Не ммх ещё. Это какой год? 1993?
Или вот опять, снова по тем же граблям ?

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

(Кстати, мне интересно, у них там по-прежнему SRT, или хотя бы Goldsmith применили?)
Или вот опять, снова по тем же граблям ?
Глабли похожие, но другие. В FDIV-баге всё было детерминировано. Тут же — всё зависело от температуры процессора. Что делало, конечно, баг очень весёлым для поимки. В итоге эта модификация «в свободную продажу» не пошла, насколько я знаю. Если вы не Amazon/Facebook/Google (которые получают новые процессоры до их официального объявления да ещё и со скидкой — именно чтобы «в случае чего» такие баги отловить), то вам на эту бяку без разгона нарваться не грозит.
За 10 лет продакшн работы я встречал наверное тысячи баги, из которых ноль связанных с железом
Повезло. За почти 20 лет Delphi видел: битую память, битые сидюки (этих штук 10), битые сети — то постоянно. Переразозногнанные процы, несколько раз. Первое вот что вспоминается.

Напомню, что хороший программист на фортране может писать на фортране на любом языке. И с приличной вероятностью при переписывании на раст будет ощутимая доля разработчиков, которые будут фигачить get_unchecked оборачивая в unsafe не задумываясь о соблюдении необходимых инвариантов, как они делали в си, или, с обоснованием что так быстрее, сделают свой RefCell, позволяющий получить &mut T дважды и рассказывая потом что нигде в коде его дважды не дёргают.


С переписыванием криптографии всё очень непросто (хотя есть rustls/ring, как пример), но получение гарантированного поведения (в том числе по влиянию на кэши, предсказатель переходов и т. п.) даже в случае шифров использующих банальный ARX или проверки MAC может быть нетривиально из-за оптимизаций.

Даже если так, это все равно лучше, когда можно грепнуть все unsafe и проверить, что safe-обертка над ними соответствует правилам.

А кто платит за переписывания Директа на Java?

> Хотите действительно безопасности?

Мы хотим адекватного компромисса.

То есть любой возможный будущий репорт стоит 100% ресурсов и полной заморозки проекта на срок равный его прошлой разработке? И у нас точно нет других, чуть менее дорогостоящих, способов с этим жить?

А параллельно разрабатывать мы уже не умеем что ли? Портировать существующую кодовую базу не требует задействовать все 100% ресурсов. Это задача несравнимо проще, чем разработка этого продукта с нуля. Более того, многие используют транспайлеры как переходный этап. Код будет не очень красивый, но он будет и сразу. А дальше постепенно его рефакторить.
А зачем мне параллельно писать с выхлопом нулевым, если я этих же программистов посажу на текущую кодовую базу, где они будут писать сразу что-то полезное?

Вы ещё спросите, зачем нужен рефакторинг. Можно ведь хяк-хяк и в продакшн

Интересный перепрыг с темы «Переписывание на другой ЯП» на «Рефакторинг кода на текущем ЯП». Это совсем не одно и тоже.

А какая разница, если в результате код становиться лучше и удобнее для использования, расширения и масштабирования в будущем? Ну кроме наверное переучивания программистов.

При рефакторинге кодовая база та же, процесс улучшений контролируемый и итеративный. Как бы… Отличия фундаментальны.

С чего бы ему становиться однозначно лучше?
В одном случае, речь о более-менее протестированном и известном коде с известными нюансами и особенностями работы, в другом — о подобии черного ящика, который еще тестировать-не_перетестировать… И, что самое забавное, в итоге получить примерно то же самое и это еще в лучшем случае.
Эм, я несколько смущён, у вас есть понимание, что такое переписать какой нибудь проект более чем на 100-1000 строк с нуля полностью на другом языке? Это годы работы второй команды. Посмотрите сколько у Mozilla ушло на создание прототипа движка Quantum на Rust, который они медленно отдельными изолированными компонентами впиливают в основной проект ;)

Справедливости ради, они всё-таки не переписывали "с минимальными правками", а наоборот всячески экспериментировали.


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

Справедливости ради, они всё-таки не переписывали «с минимальными правками», а наоборот всячески экспериментировали.

Это то понятно иначе смысла переписывать вообще не было бы никакого.

Параллельно. Итого мне теперь надо не 100% ресурсов, а 200%. Плюс "старая" команда, поддерживающая продукт будет демотивирована постоянно и бонусом мы получаем внутренний конфликт в компании.
Кроме этого, новый код будет постоянно отставать от плюсового. Не получим ли мы не 10 лет на разработку, а 15?
Кто это оплатит?

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


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

Лично я считаю, что основной причиной переписывания Firefox на Rust является популяризация Rust и не более (да, я читал их посты о том, что они не смогли в С++ и теперь у них волосы мягкие и шелковистые). Зачем они это делают? ИМХО — хотят иметь «свой» язык по аналогии с C# у MS, Kotlin у JB, etc. Зачем им это? Не знаю.

Полтора года не растёт. Вначале был всплеск и доля c++ начала падать. А потом всё остановилось. И так оно уже долго.

Всё относительно. Они скоро выкатят в релиз обновлённый Firefox на мобильные платформы, с удобным дизайном и который в отличии от старого успешно работает на старых железках с 1 ГБ памяти. В общем посмотрим. Firefox реально лучше любой хромоножки, приватность данных, расширения на могильных платформах. Уже в 12 году вернулся на Firefox и не жалею, он реально для людей делается. Да и это единственный теперь браузер в котором uBlockOrigin полноценно работает.
расширения на могильных платформах

Понимаю, что опечатка, но не могу не спросить — это на Windows Phone, что ли?..

На всех поддерживаемых. Я все мобильные платформы так называю переодически :) Они все, скажем так, урезанные, с закрученными гайками и не полноценные для многих задач. Последними нормальными мобильными полноценными ОС были Symbian и Windows Mobile. Сейчас всё слишком весело. Дабы не углубляться в тему слишком глубоко, просто оставлю в качестве примера Don't kill my app!, на Android с этим местом отдельные проблемы, на iOS просто невозможно запустить фоновый процесс с гарантией того что он не будет убит.
Это вы сейчас про то, что при открытии нескольких вкладок в браузере андроид убивает висящий в фоне и играющий музыку плеер?
висящий в фоне и играющий музыку плеер?

у меня не убивает — что я делаю не так? А, точно — это ж у меня в фоне ютуб премиум фигачит

У меня фубар, задрало, что вариант использования браузером — открыл по ссылке новую вкладку, прочитал, закрыл.
Почему, блин, на 3гб памяти я не могу просто послушать в фубаре фоном музыку! На винфонах там я только на совсем дохлой люмии при каких-то странных страничках подобное пару раз встречал (которые вешали браузер), а тут — на постоянку…
У меня в смартфоне 6 ГБ и приложения убиваются, музыка обычно работает, но вот всё настолько гнило что виджеты, например, кроме системных часов, не обновляются вообще или обновляются иногда но с чем это связано — не ясно. Даже закреплённые в недавних приложения просто исчезают и перестают быть запущенными, OnePlus 7 Pro. Скатился производитель в говно оказывается, а я этот момент пропустил ибо до этого был 3T где никаких таск киллеров сторонних не было.
Это зависит от версии ОС, ну и поскольку open source то есть производители-мудаки которые туда ещё свои тасккилеры пихают.

Ну так даже если МС от него откажется, то он и правда останется жить, разве нет?

Разве нет. В течении более, чем 10 лет Microsoft стремился к тому, чтобы между C# и Windows устновилась, в головах, прочная связь. А дальше — планировалось, что Windows будет везде и одним из агрументов для этого будет «классный язык C#».

Как у классика: Ничего не будет. Ни киноGNU, ни театраEmbedded, ни книгSymbian, ни газетBlackberry – одно сплошное телевидениеWindows.

Когда проект Windows Phone «накрылся медным тазом» и стало понятно, что аргумент «C# отлично работает на Windows и за будьте про всё остальное», скорее, заставляет разработчиков выбирать Java (Python и прочее) и уходить с Windows — произошёл разворот на 180 градусов, Visual Studio начала поддерживать вот это вот всё… и C# начали птытаться сделать «кроссплатформенным».

Но… поздно метаться: слишком много вещей, которые считаются «само собой разумеющимися» в C#-мире по прежнему привязаны к Windows.

Так что сегодня C# добрался только лишь до стадии: «хорошо под Windows и, если очень надо, можно чуть-чуть для чего-то ещё».

Этот статус позволяет ему жить, но если Microsoft от C# откажется — смысл в нём исчезнет немедленно.
Но… поздно метаться: слишком много вещей, которые считаются «само собой разумеющимися» в C#-мире по прежнему привязаны к Windows.

Это каких таких в контексте .net core? Если убрать UI (WPF/WinForms) составляющую
Это каких таких в контексте .net core? Если убрать UI (WPF/WinForms) составляющую.
Понятия не имею какую там нужно составляющую убирать и откуда, но у меня несколько знакомых (не программистов) искали хостинг для своих ASP.NET проектов — на дешёвых хостингах с Linux не заработал ни один.

Что там технически происходит — я не в курсе, но связь «C# = Windows, а C# под Linux — для тех, кому нужно приключений на свою задницу» это поддерживает устойчиво.

Я не знаю, что там на дешевых хостингах, но в контейнерах все работает прекрасно у кучи компаний (из российский на слуху озон, додо, каспер и т.д)

У кучи компаний оно работает, потому что у них стояла задача «запустить это всё под Linux» — и был выделен на это бюджет.

А у энтузиастов бюджета нету: если у вас выбор, условно, платить $10 в месяц или $20, но перед этим заплатить программисту $300-$500 для адаптации… то простая логиика подсказывает, что вы таки будете платить $20.

В Java, к примеру, этого нет, потому что все пакеты изначально проектировались и затачивались, в том числе, под Linux.

Если пилить проект изначально под .net core, то все прекрасно будет работать под Linux.

Вот только основная масса C#-проектов — уже «запилены»… и не под Linux.

Ну так пусть живут не под Linux. Выгодно будет переписать — перепишут. Это не так и сложно, если нет компонент, прибитых к винде. Но это уже не относится к .net

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


Можно было бы обойтись куда меньшими правками и перенести вообще в несколько раз быстрее. Но решили попутно еще пару проблем с архитектурой порешать.


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

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

Что будет если Microsoft, ну вот прям завтра скажет: «всё, мы передумали, нам играться в кор более не интересно, проворачиваем фарш назад, мясо — корове в зад… возвращаемся на Windows»?

Скорее всего тех, кто будет продолжать «переписывать на кор» — станет резко меньше, а тех кто будет «даже на питон» — резко больше.

И всё. И кончится C#, который, якобы, давно перерос Microsoft.

Вот лет через 5-10, когда на версии для Windows останется только небольшая часть сурового Legacy. И когда разработчиков C# вне Microsoft будет больше чем внутри… да, тогда можно будет сказать «да, C# уже перероc Microsoft».

А сейчас — ещё нет. Да, движение в этом направлении идёт… но пока ещё — C# очень сильно завязан на Microsoft…
По-моему вы яростно соглашетесь со мной. Вот смотрите — сейчас ситуация такая, что «на виндовом фреймворке оставаться не желает никто», но при этом часть «переписывают на кор», а часть «даже на питон переписывает».

Понятное дело что есть процент легаси всегда. В тех проектах, на которых я работал и они были мне интересны цифра виндвого фреймворка была 5-30%.


А сейчас — ещё нет. Да, движение в этом направлении идёт… но пока ещё — C# очень сильно завязан на Microsoft…

Я нигде не говорил что C# будет отвязан от майкрософта, скорее наоборот. Это как котлин и жетбрейнс, умрут последние — котлин резко потеряет в коммьюнити. Умрёт гугл — скорее всего го резко исчезнет с радаров.


C# отвязан от винды, уже давно и это так. Но он совсем не отвязан от майкрософта, и скорее всего, никогда не будет.

Так что сегодня C# добрался только лишь до стадии: «хорошо под Windows и, если очень надо, можно чуть-чуть для чего-то ещё».

Вот с этим утверждением.

С ним можно было бы спорить, если бы массовый переход на core уже состоялся. Но нет — он в самом разгаре «у компаний в теме». А «мелочь пузатая» подтянется лет через 5-10.
С ним можно было бы спорить, если бы массовый переход на core уже состоялся

Состоялся. О чем я уже не раз говорил. Сидят всякие легаси-монстры, которым и COM нужен, и AD, и прочие. Все b2b SAAS — уже там.


Но нет — он в самом разгаре «у компаний в теме». А «мелочь пузатая» подтянется лет через 5-10.

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

Всё наоборот, мелочь пузатая как раз быстро и чутко адаптирует новые стеки, а догоняющими являются «компании в теме».
В данном случае я имею в виду не стартапы какие-нибудь, а булошные и кафешки. Которые вообще своего IT-отдела не имеют и заказывают переработку своего сайта/бухгалтерии раз 3-5-10 лет. Ну те, которые плачут горючими слезами про то, что поддержка Windows 7 закончилась (а некоторые — так и с Windows XP не слезли). Они ещё даже не почесались со времени появления .NET core, не то, что не перешли.
В данном случае я имею в виду не стартапы какие-нибудь, а булошные и кафешки.

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


А те булошные и кафешки что с нами работают, например, получают от нас мобильные приложеньки или веб-морду и не знают, что работают на кор2.0-3.1

Microsoft прям уже выпустило последнюю версию .NET Framework если че и развивать его не будет. Дальше только .NET 5 (ветка .net core)

Wiki:
Как было объявлено, следующая версия будет называться .NET 5 (без использования «Core» в названии). В .NET Core 3.0 был почти полностью устранен разрыв в возможностях с .NET Framework 4.8. Новая версия станет единой платформой для .NET разработки, заменяя Mono и .NET Framework.

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

Жить (или доживать) он останется точно. Продолжит ли он развиваться — я не знаю. Я не уверен.
основной причиной переписывания Firefox на Rust является популяризация Rust

Не только, ты же знаешь что в Rust есть несколько вещей, которые позволяют компилятору лучше генерировать код и вот прямо сейчас это уже работает правда пока ещё не так идеально как если бы работало в полную силу, но ничего, frontend допилят, особенно после того как древние баги clang на middlend починят.

Mozilla foundation преследует вполне понятные цели: обезопасить код, работающий с пользовательскими данными (код сайтов для них ведь тоже пользовательские данные) именно поэтому у них многослойные тесты на всё и всех для участков кода на всех используемых языках. Rust тут помогает некоторую, вполне конкретную, часть дыр прикрыть на корню, что явно на пользу. В общем то было бы удивительно что если бы новый системный язык (дефакто это 3 системный язык после C и C++) с первой спецификацией в 15 году не был бо лучше предшественников.

Да и я бы не сказал что в Mozilla не осилили C++, наоборот. Они просто выбрали альтернативный вариант. Они могли бы переписать однопоточный и даже одно процессный свой старый движок тоже на C++, но поскольку очевидно, что архитектура проекта будет принципиально иная много где они решили эти места написать на Rust. По мне это довольно разумное решение. Кроме того, насколько я вижу они сейчас переписывают разный код который «по быстрому адаптировали» в интерфейсе браузера за последние несколько лет с JS на C++. В общем по мне всё у них всё последовательно и логично.

Уменьшение багов? Я вот, ради интереса, перевёл проект с Mono на Net Core и с удивлением обнаружил, что багов стало больше. Пришлось писать workaround-ы.

Есть подозрение, что это скорее перестали работать хаки, которые работали под моно.


Не поделитесь ссылкой, какие баги там где всплывают и в какой версии рантайма?

Ссылкой не поделюсь, потому что её нет. Могу просто описать баги:

1. Приложение — мультиплексирующий прокси, который держит единственное соединение с сервером по https и несколько клиентских. Сервер иногда дропает соединение, приложение это отлавливает и переподключается.

Так вот: SslStream не всегда ловит ситуацию, когда соединение было закрыто, вместо этого уходит в бесконечное ожидание. Дальнейший анализ проблемы показал, что он висит на Socket.ReceiveAsync. Причём асинхронщина используется, даже если используются только синхронные вызовы в SslStream.

Но при этом он зависает не намертво. Если при этом отключатся все клиенты, то после этого таки происходит завершение Socket.ReceiveAsync.

Проблема устойчиво воспроизводится в Net Core 3.1.201 под Ubuntu. Под Mono и в Windows она не возникает.

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

2. Проблема при использовании SafeHandle и interop. Дело в том, что в Linux дескриптор имеет тип int (32 bit), а внутри SafeHandle используется IntPtr (64 bit в 64-битных системах). Mono об этом знает, и если функция выдаёт значение -1 (некоррекный дескриптор), то делает знаковое расширение до 64 bit, а вот NetCore делает беззнаковое расширение, в итоге функция SafeHandle.IsInvalid работает некорректно.
Ну уж о второй-то ошибке стоило отписать.

Как раз пример того, что может случитс на платформе, на которой мало кто из разработчиков работает…
  1. Нужно проверять в одинаковых условиях, работа моно под винду совсем не гарнатирует работу того же моно под убунту
  2. А вот на это я бы заводил issue, выглядит как серьёзная проблема.

Вы правы, legacy переписывать не очень выгодно. Тем не менее COBOL и FORTRAN практически исчезли, уйдёт и C++ по тем же причинам. Rust тоже исчезнет, но C++ грозит упадок гораздо раньше.

Не уверен, c++ развивается. И это заметно среди c++ разработчиков. Лично знаю нескольких, которые крепко думали о переводе проектов на rust, но c++ 20 в итоге перевесил.


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

Всегда интересовало — как люди решаются переводить проект на условный С++20, когда:
  • Он ещё официально не вышел
  • Поддержка компиляторов всё ещё совсем такая себе (имхо — недостаточно стабильно для серьезного прода)


Или это проекты в пару единиц трансляции и не являющиеся серьёзным продом?

Думаю имеется в виду "хотели начинать/переводить проект на Rust из-за недовольства C++, но новые фичи из C++20 потенциально делают C++ менее раздражающим, а значит можно продолжать писать пока на нём".


Поддержка компиляторов всё ещё совсем такая себе

Через год-другой, думаю можно будет уже постепенно тащить в прод.

В отличие от кобола и фортрана, С++ развивается. И развивается довольно сильно. Так что сравнение мягко говоря некорректное. Основное различие между Rust и C++ тут только в том, что C++ старается развивается обратносовместимо со всей кодовой базой, наработанные за долгие годы. У Rust такого груза пока что нет. Вот и вся разница.

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

C++ может позволить себе выкатывать фичи в виде TS и опробовать их на смелых пользователях, послего чего выкатывание фичи происходит после успешного прохождения всех тестов (и это всё равно не мешает падать компилятору на коде того же tdesktop при масс-ребилде той же Fedora). Хз, может они тоже билдят какие-то проекты — я хз, какая там политика у каждого компилятора.

Я рад, что Rust может позволить себе перекомпилировать все крейты, только это всё равно ничего не гарантирует, хоть и увеличивает шанс, что всё хорошо :)
Хм, не знал, что его так активно пилят. Тогда про фортран точно неправ.
да ничего он не убьёт. В РФ открытых вакансий по Rust пара штук + крупные фирмы типа Яндекса должны перейти на него, чтобы взлетел.

К счастью, Российской Федерацией мир не ограничивается.


В Яндексе, может быть, и не добавят Rust в список разрешённых языков. Не успеют…

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

О, там C++ головного мозга очень и очень у многих в верхушке компании. Так что доклад Полухина можно считать официальной позицией Яндекса (но не всех сотрудников Яндекса, это разные вещи).

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

Почему? Потому что я не вижу смысла в переходе на этот язык и дроблении экосистемы на ещё один ЯП. И если растоманы постоянно его везде рекламируют — что же, пора просто начинать пропаганду в обратном направлении, чтобы компании меньше переходили на Rust и больше думали о том, что будет с их кодом через 20 лет.
Поддерживаю. Маркетинг в отношении ЯП — это уже нечто несколько за гранью если не разумного, то инжинерного точно.
Уже давно такие вещи перестали быть только инженерными, если что. Как банальный пример — выбор библиотеки зачастую происходит исходя из условных звёздочек на GitHub. А как их нафармить? Постами на профильных ресурсах, форсить в Твиттере и вот это всё — создавать активность вокруг. А это и есть маркетинг.

Здесь тоже самое, только в случае ЯП.

Ну так звёздочки на гитхабе это вполне объективный способ выбора библиотеки.
Чем больше звёздочек => тем больше юзеров => больше гайдов.
Причём если у тебя появляется какая-то проблема, то с 99% вероятностью её решение ты найдёшь только для той либы, которая имеет тысячу звёздочек а не 10.

Я немного про другое. Есть две либы. Одна написана внутри хорошо, эффективно, фичастая, багов мало. Но при этом автор её тихо пилит, она где-то валяется на гитхабе, крейты создаются потиху и всё.

Вторая же сразу начала активно пиарится, но при этом уступает первой по всем вышеперечисленным параметрам. По моим наблюдениям звёздочек у первой будет больше. Хотя скорее всего вам бы больше понравилась первая либа.
То есть вы не видите смысла для себя, и прикладываете усилия для того, чтобы проект не начинали другие люди? :)

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

И если вам приходится отвечать на рекламу пропагандой — ну, видать дела у вас совсем плохи :)))

А что с их кодом будет через 20 лет? А что сейчас с кодом, которому даже не 20, а хотя бы 10 лет?

Сейчас C++ по отношению к Rust оказывается в том же положении, в каком был C по отношению к С++. И даже аргументы те же. Скажите, вот что в вашем комментарии не применимо к переходу с C на С++? И где теперь этот C?
То есть вы не видите смысла для себя, и прикладываете усилия для того, чтобы проект не начинали другие люди? :)

Да, совершенно верно. Потому что мне с их кодом потенциально работать.
И если вам приходится отвечать на рекламу пропагандой — ну, видать дела у вас совсем плохи

Это ровно то же самое, что делает Rust. Не вижу ничего зазорного отвечать в той же манере :)
А что с их кодом будет через 20 лет? А что сейчас с кодом, которому даже не 20, а хотя бы 10 лет?

А что, там все либы Rust, написанные за какие-то там 5 лет, успешно собираются последними релизами?
Сейчас C++ по отношению к Rust оказывается в том же положении, в каком был C по отношению к С++. И даже аргументы те же. Скажите, вот что в вашем комментарии не применимо к переходу с C на С++? И где теперь этот C?

Не применим относительно «бесшовный» переход. Потому что С++ хоть и не является полным надмножеством С, но очень-очень с ним совместим. И это значительно облегчает переезд. А где С? Он везде. Ровно там, где ему и место :) Никто в здравом уме не потянет С++ или Rust в код, который испокон веков был написан на С и будет дальше на нём писаться.
Потому что С++ хоть и не является полным надмножеством С, но очень-очень с ним совместим.
Ага, конечно. Есть только C программа не испольщует malloc/calloc и работу с памятью.

Дурацкий вопрос: вы вообще много C-программ без malloc/calloc видели?

А вообще и ваши истерики и статьи Полухина — это не просто хорошо, это прекрасно.

Потому что такое уже случалось в истории много раз. Когда представители платоформы-лидера начинают выпускать статьи и телепередачи «да не нужен вам XXX, бросьте каку» — это значит что всоре они будут уже называться «бывшим лидером». И неважно — речь идёт о переходе с Lotus 1-2-3 на Excel или с Microsoft IIS на Apache. Результат один и тот же.

Никто ведь не выпускает статей на тему «почему вам не стоит переписывать ваш код с C++ на C#»… а почему? А потому что тот код, который можно перевести с C++ на C# — уже перевели, переписали, а тому, который не переписали — это и не грозит.

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

P.S. Впрочем как показал опыт перехода с C на C++… никуда C++ не денеться. И через 10 и через 20 лет будут люди, который будут на нём писать. Так что в этом смысле вам ничего не грозит.
Ага, конечно. Есть только C программа не испольщует malloc/calloc и работу с памятью.

А если использует, то что, она совсем иной становится? Да, я знаю про начала лайфтаймов и различие в этом плане между new/malloc. Но даже учитывая это, я считаю эти два ЯП сильно похожи.
А выдеоролики, подобные обсуждаемому, появляются… то значит пора, по крайней мере, начинать играться с Rust.

Так это наоборот правильное решение! Я настоятельно рекомендую многим людям попробовать Rust. Это действительно полезный опыт. Например, хорошо людей приучает, чтобы всё было константным by-design. И много чего ещё полезного.
P.S. Впрочем как показал опыт перехода с C на C++… никуда C++ не денеться. И через 10 и через 20 лет будут люди, который будут на нём писать. Так что в этом смысле вам ничего не грозит.

Я за это не переживаю. Я прекрасно понимаю, что сейчас рождено столько кодовой базы, что мне до моей смерти хватит работы. Я не хочу, чтобы люди на ровном месте бросались переписывать всё на Rust, вот и всего. Также как и начинали писать что-то новое на технологии, которая не показала такой уровень стабильности, как C++.
Я не хочу, чтобы люди на ровном месте бросались переписывать всё на Rust, вот и всего

это хорошее замечание. И действительно — не нужно тратить силы на переписывание чего-то, если их можно направить на создание чего-то принципиально нового. А если силы остались — начать то что называют housekeeping.


Также как и начинали писать что-то новое на технологии, которая не показала такой уровень стабильности, как C++.

ну, это фанатизм. По мне там C# и Java куда более стабильные, чем C++

А если силы остались — начать то что называют housekeeping.

Да! Это абсолютно верная стратегия.
ну, это фанатизм. По мне там C# и Java куда более стабильные, чем C++

А я ничего плохого в их сторону и не говорил. Я слабо знаком с их миром, но насколько я знаю — они тоже достаточно стабильны. Но точной инфы у меня нет.
А если использует, то что, она совсем иной становится?
А если использует, то она не скомпилируется. Потому что в C++ нельзя написать struct S s = malloc(sizeof s);. Надо struct S s = (S*)malloc(sizeof s); как минимум. Но кто-то может «для красоты» и в S s = new S; превратить. Оставив, по прежнему, в точке деаллокации free(s);.

Опять-таки в C11 вы можете написать struct S s = {0}; и потом сравнить две такие структуры через memcmp. А в C++ — не можете.

В общем переход с C на C++ — это большая работа. Не просто опии компилятора поменять.

Согласно текущим стандартам C++, недостаточно просто скастовать. См. http://wg21.link/p0593r6, там первым примером идет объяснение того, почему так. Если/когда этот документ будет принят, то будет можно — в C++20 или С++23.


А пока для полного соответствия стандарту надо писать


S* s = new(malloc(sizeof S)) S;

Миф про то, что переход с C на C++ тривиален, был показательно развенчан в видео https://www.youtube.com/watch?v=0dkzLdqH9V4, где автор 10 часов потратил на то, чтобы только скомпилировать исходный код Chocolate Doom (причесанный портабельный С-код) в режиме C++

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

Также как и начинали писать что-то новое на технологии, которая не показала такой уровень стабильности, как C++.

Это когда баги поддержки стандарта в компиляторах находятся регулярно (не кодогенерации, а именно поддержки на стороне фронтенда), когда о поддержке C++98/03 можно было говорить лет через 7 после его релиза, когда компиляторы учатся адекватно оптимизировать новые конструкции через 3-7 лет после их релиза в языке?


Я не знаю, что в C++ стабильно, кроме job security на некоторых кодовых базах.

Я не знаю, что в C++ стабильно, кроме job security на некоторых кодовых базах.

отличный троллинг! А еще, наверное, и не только job security, но и з/п выше среднего по рынку? Ну, с++ники — же элита и все как один с 10+ лет синьорского опыта

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

Ну, с++ники — же элита и все как один с 10+ лет синьорского опыта

Кто вам такое сказал? :) Это ровно такие же работяги, как и условные фронтендщики. Пришёл на завод, смену отпахал за gcc-станком, ушёл. Насчёт ЗП — да хз, вроде вполне себе средне\медианная по рынку.
Хз, уже писал выше, что отладчик открываю очень редко. Но это снова же «ошибка выжившего», конечно же :)

Это было бы ошибкой выжившего, если бы действительно стреляло (и не в ногу). Или компании, производящие код с memory corruption и т.п., разорялись. А так это выборка с N=1.

когда о поддержке C++98/03 можно было говорить лет через 7 после его релиза

В тоже самое время С++20 ещё до своего выхода очень неплохо поддержан GCC 10. Времена меняются. Но это не касается всяких проприетарных компиляторов.
когда компиляторы учатся адекватно оптимизировать новые конструкции через 3-7 лет после их релиза в языке

Тут я тоже не знаю, что ответить. Потому что практически все известные мне оптимизации происходят там, где от С++ кода уже ничего не осталось.
Я не знаю, что в C++ стабильно, кроме job security на некоторых кодовых базах.

Совместимость.
Совместимость.

Ну давайте, расскажите мне про совместимость того же манглинга в минорных версиях одного компилятора, к примеру, гцц))

Совместимость на уровне языка, конечно же. ABI не стандартизирован и это проблема, да :(
Поддержка компиляторов всё ещё совсем такая себе (имхо — недостаточно стабильно для серьезного прода)
В тоже самое время С++20 ещё до своего выхода очень неплохо поддержан GCC 10.

Ну ё-моё.


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

Что не мешает хорошо оптимизировать std::min({ a, b, c }) в изолированных примерах, но спиллить регистры, когда окружающий код не столь тривиален.


Совместимость.

Это было бы так, если бы компиляторы не переставали принимать код, который они ранее некорректно принимали.

Ну ё-моё.

Всё верно. Для прода — не годится. Пробовать фичи — годится. Вон кому-то Nightly версии компилятора нормально. Кому-то грейдить страшно компилятор до выхода нескольких патчей. Так что нет никакого противоречия.
Что не мешает хорошо оптимизировать std::min({ a, b, c }) в изолированных примерах, но спиллить регистры, когда окружающий код не столь тривиален.

Репорты на перф-дефекты отправлены? Каков ответ?
Это было бы так, если бы компиляторы не переставали принимать код, который они ранее некорректно принимали.

Баги есть везде :) Это очевидно, вроде как.
Репорты на перф-дефекты отправлены? Каков ответ?

Дефект уже был известен, как я понимаю. В шланге 10 починили, но этой фиче, блин, 9 лет.


Баги есть везде :) Это очевидно, вроде как.

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

Что-то там совсем не так с проходами оптимизации, если такая ерунда остаётся.

Там не с проходами оптимизация беда, с аттрибутами что-то. Заметьте, что если вы уберёте -stdlib=libc++, то это фигни не будет.

Разница в том что в libstdc++ tuplenon-trivial for the purposes of calls, а в libc++ — как раз trivial (сравните). Соответственно когда этот самый tuple оказывается в одном регистре дальнейшая попытка это распутать обламывается.

Тут, как бы, проблема даже не в том, что такое имеет место быть, а в том, что это, блин, банальный инлайниг. Без какого-то сложного control flow. С которым, как нам говорили, уже много лет назад «всё хорошо». И вот — регулярно вылазят такие косяки… в 2020м году, блин.

P.S. Или если увеличить результат, так чтобы он перестал влазить в регистр… то крабс-бамс-бемс… всё перестало влазить в регистр, «расклеилось» и свернулось.
Это было бы так, если бы компиляторы не переставали принимать код, который они ранее некорректно принимали.

Справедливости ради, в Rust это тоже есть — при переходе со старого borrow checker-а на NLL выловили несколько мест, которые в переходный период (около года, если не ошибаюсь) выдавали предупреждение, а потом стали ошибками. Но — единичный случай ввиду крупной перестройки, и, да, с предупреждением за несколько версий до слома.

Таки это была серьёзная правка, блокирующая сборку невалидного кода. Исправление таких ошибок в компиляторе гарантированно болезненно.

А с таким подходом, не будет ни кода, ни компании такой, ни вас внутри той компании через 20 лет.
Причем раст они (яндекс) не добавят именно стараниями Полухина, судя по всему.
ваше утверждение основано на большом количестве спекуляций. Например на том, что мнение Полухина имеет решающий вес будет ли принят раст, на том, что раст экономически целесообразен для яндекса, на том, что профит от переписывания десятков тысяч человеколет плюсового кода на раст превзойдет затраты…
Все ведь потихоньку в этом направлении и движется, тот же микрософт вот уже сапера на расте пару дней назад выложил.
тут такое «потихоньку», что к тому времени когда раст станет полноценной заменой с++ разовьется достаточно чтобы смысла писать на расте не было…
Да, забавно, как быстро можно докатиться до теорий заговора. Microsoft написал сапера на расте, а Яндекс не написал — значит, это потому, что лично Полухин занимается вредительством.
Например на том, что мнение Полухина имеет решающий вес будет ли принят раст, на том, что раст экономически целесообразен для яндекса, на том, что профит от переписывания десятков тысяч человеколет плюсового кода на раст превзойдет затраты…

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


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

… тогда получается уже не очень хорошо.

Получается хорошо. Чтобы люди брали проверенные временем и поддерживаемые десятилетиями технологии. Всё так.

А наколенные вещи можно действительно писать на чём угодно, хоть на Rust, хоть на Python.
Получается хорошо. Чтобы люди брали проверенные временем и поддерживаемые десятилетиями технологии.

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

А про какую «ложь во благо» речь? Про то, что дезинформация в докладе Антона была? Так это, комментарии ниже почитайте с ответами :)

Прочитал. Все еще придерживаюсь позиции, что по большей части, все перечисленное в статье — так.


А про дезинформацию: возьмем конкретный пункт "Плюсы Rust только в анализе времени жизни объектов." Это откровенная, явная неправда в такой формулировке, потому что как минимум раст похволяет не только контролировать лайфтаймы, но и отсутствие 2-х мутабельных ссылок на данные (ownership), в отличии от C++. Более того, ниже автор доклада явно повторил эту формулировку "Поэтому да — только lifetime", так что вопросы некорректной интепретации видео снимаются.


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

Так по большей части или полностью? :) Чтобы вы сразу понимали — я тоже не полностью согласен с тем самым докладом Антона.

Я никакой лжи в своей речи не вижу. Я вижу только то, что как Rust-community насаждает Rust, так и я, как представитель C++-community, насаждаю С++. И своими словами я нигде, вроде как, ложь про Rust как про ЯП, не сказал пока что.

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

"Все" действительно лишнее, вы правы.


Я никакой лжи в своей речи не вижу

А вас я во лжи и не обвинял нигде. Давайте восстановим, как было дело:


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

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


Далее вы пишите:


Получается хорошо. Чтобы люди брали проверенные временем и поддерживаемые десятилетиями технологии. Всё так.

То есть поддерживаете позицию, что можно говорить что угодно, главное — чтобы выбрали вашу любимую ("проверенную временем") технологию. И вот эту позицию я не разделяю.


Rust-community насаждает Rust

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

То есть поддерживаете позицию, что можно говорить что угодно, главное — чтобы выбрали вашу любимую

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

Я был бы рад ошибаться. Но когда налетают коршуны со словами «Переписывайте на Rust» вместо дальнейшего поддержания существующего кода и допиливания в него новых фичей вместо тупого переписывания — мне это очень и очень не нравится. Лучше пусть пилят что-то новое (как хороший пример — самый адекватный Matrix сервер сейчас пишется как раз на Rust и это круто).
Я всего лишь придерживаюсь позиции, что если они останутся на С++, то это с моей точки зрения хорошо.

зачем? Цель какая? Типа все, кто не на С++ пишут — не развивают экосистему? Ну, так и те кто пишут — не все развивают. Не понимаю


Но когда налетают коршуны со словами «Переписывайте на Rust» вместо дальнейшего поддержания существующего кода и допиливания в него новых фичей вместо тупого переписывания

ну, тролли есть всегда и везде )

зачем? Цель какая? Типа все, кто не на С++ пишут — не развивают экосистему? Ну, так и те кто пишут — не все развивают. Не понимаю

Да, совершенно верно. Если они останутся, то шанс развития экосистемы выше, чем они не останутся. Да, я понимаю, что далеко не все развивают экосистему (и это абсолютно нормально).
ну, тролли есть всегда и везде )

Так ладно если б тролли — троллинг это хорошо. Так не троллинг ведь зачастую. Потроллить и я могу, зайдя в условный diesel и сказать, что чот медленно как-то, го перепишем на нормальный быстрый бумерский С++ :)
Прикольно, когда под технической статьей кто-то открыто приводит доводы, оправдываемые своими же шкурными интересами…
А зачем, если переезд бесшовен практически? Это не переписывание полностью кода на другой ЯП. Это, пожалуй, замена всех auto_ptr на unique_ptr, да? И ещё, пожалуй, проверка, чтобы из деструкторов исключения не летели (или пометка их как noexcept(false))

У меня для вас два слова: MSVC и шаблоны. Ну и где-то эхом разносится "зависимостии-и-и".

Это имеет слабое отношение именно к С++ как к Стандарту языка :)

msvc как реализация давно славился своей «интересной» трактовкой Стандарта. На это можно только сказать, что все претензии к вендору :) Сейчас и сам msvc исправляется очень быстро, и Clang на винде уже доступен. Если у вас msvc-specific код — что ж, тогда больно будет (но и тут мб поможет clang-cl).
Но зачем тогда было переходить с, не знаю, кобола на плюсы? Проверенная временем технология же.
Но когда люди стоят перед выбором «а не начать ли нам новый проект на Rust?», а им попадается доклад Антона, тогда получается уже не очень хорошо.
то есть вы считаете что люди не должны обладать полной информацией и не должны иметь доступ к обеим точкам зрения по поводу раста?

Этот доклад не претендует на полноту информации, а скорее пропаганда "раст плохой, бросьте бяку". Притягиванием за уши каких-то сценариев и откровенной ложью.

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

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

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

Это возражение переносится один-в-один на С++: "Один UB может убить все проверки С++, так что С++ не даёт никаких преимуществ перед C."


если бы в расте нельзя было отключить borrow checker

Borrow checker в Rust не отключается. То есть не отключается в том же смысле, что в С++ не отключается RAII. Да, можно написать код, который borrow checker не будет проверять (с использованием raw pointers и unsafe), но это не значит, что borrow checker в этом коде отключен.

Да он просто ничего не проверяет и толку от его наличия нет никакого.
Да, можно написать код, который borrow checker не будет проверять (с использованием raw pointers и unsafe), но это не значит, что borrow checker в этом коде отключен.
borrow checker в таком коде не работает, «но это не значит что borrow checker в этом коде отключен»? Противоречие

Только ансейф и нужен чтобы работать с сырыми указателями. Все ансейф блоки которые я встречал работали внутри на 95% именно с сырыми указателями. То что 5% ансейф кода прочекается — это сомнительное достижение. С учетом того что уб сделанное в ансейф коде может выстрелить абсолютно в любой момент, уже после ансейф.

Он работает, но не проверяет лайфтаймы сырых указателей.
ну сами посудите. unsafe в большинстве случаев нужен либо для того чтобы работать с сырыми указателями, либо чтобы вызывать unsafe функции которые вызывают unsafe функции… которые работают с сырыми указателями. Итак, вопрос: если я пишу unsafe чтобы поработать с сырыми указателями вместо ссылок/Box'ов, отключаю ли я borrow checker?
Итак, вопрос: если я пишу unsafe чтобы поработать с сырыми указателями вместо ссылок/Box'ов, отключаю ли я borrow checker?

Нет, не отключаете ¯\_(ツ)_/¯

Да какой пример то? Отключить borrow checker нельзя. Вам уже сказали — borrow checker продолжает работать в unsafe секциях, но он не предназначен для указателей by design. Но при этом продолжает проверять ссылки. Хотите пример — держите https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=29e9aef02a12d840b81919c83166a31f. А ваша аргументация — это что-то в стиле "я отключил ПДД, так как лечу на самолете".

Какой-то бестолковый спор. Суть в том что я написал выше. От ошибок с памятью в ансейф блоках борроу чекер не спасает никак.

Акценты не так расставлены. Борроу чекер не занимается спасением от ошибок при работе с сырыми указателями (и некоторыми другими), для спасения от которых он не предназначен. Такие ошибки можно совершить только в unsafe блоке.

Борроу чекер не занимается спасением от ошибок при работе с сырыми указателями (и некоторыми другими), для спасения от которых он не предназначен
А. борроу чеккер не покрывает сырые указатели
Б. работать с сырыми указателями можно только в unsafe блоке
Складываем А и Б, делаем вывод: в unsafe блоке можно нарушить гарантии borrow checker'а (используя сырые указатели), о чем я и писал выше.

А если бы это было невозможно, невозможно было бы например передать в сишную либу объект во владение по указателю.
Кто сказал?
дереференсить сырой указатель можно только в unsafe блоке. А без этого вся «работа» с указателями сведется к размазыванию инвариантов unsafe блока на safe код.
А если бы это было невозможно, невозможно было бы например передать в сишную либу объект во владение по указателю.

Поправлю. Передать без unsafe можно (если не учитывать unsafe для вызова внешней функции): Box::leak(). А вот забрать владение без unsafe действительно нельзя, так как нет компилятор не может гарантировать, что возвращается валидный указатель.

То есть не отключается в том же смысле, что в С++ не отключается RAII. Да, можно написать код, который borrow checker не будет проверять

Можно пожонглировать определениями, только какой в этом смысл?

Времена жизни ссылок всегда проверяются. Времена жизни указателей всегда не проверяются (но учитываются, см. stacked borrows). Нужно как-то сильно пожонглировать определением слова "отключается", чтобы назвать это отключением.

stacked borrows — это какой-то пропозал или эвритстика miri или что это?


По поводу второй части я написал выше

Ох очередная пдф-ка в мой to read лист. Лайфтаймы в расте доказывают что программа коректна по памяти. Что делает эта штука? Она ничего не доказывает но частично ловит ошибки, правильно? Вообщем-то как это делает другие анализаторы из miri? Значит ли это что то что в расте везде навешаны лайфтаймы то их проще вывести и для указателей* из окружающего кода? Потому что явных лайфтаймов в указателях я что то не помню.

Спасибо, но 15 минут, это вы слишком хорошего мнения обо мне. Конечно если речь про скорочтение как в 1ом классе то в 15 минут я уложился :)


Я то понял что это эвристика MIRI. Но, хмм, вроде там ограничения такие же как у борроу чекера, хотя по идее должно быть более "flexible".

Нет, у них разные алгоритмы. Борровчекер не использует stacked borrows, он вообще игнорирует сырые указатели, а мири — нет.

Да я прочёл но ещё не до конца. Вроде как для обычных референсов они тэгаются полностью через Unique(t), и пофиг stacked или не stacked оба в результате дают правило вложенности. А вот для сырых там какой то SharedRW(bottom), который не тегается. У меня сложилось впечатление что это хорошо сработает на границах safe-unsafe но не внутри unsafe. Если честно мне пдф-ка понравилась больше чем блог, там больше разжёвано.

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

Что не хорошо то? Люди хотят начать новый проект в продакшене на Rust. Это означает что его потребуется поддерживать. При всём уважении к Rust и моей радостью что его активно развивает Mozilla, подавляющее большинство компаний это не осилят ибо язык слишком сырой, а самое главное нет вообще никаких гарантий, что не выйдет новая версия которая потребует переписать всё.
Комитет C++ активно «блюдёт» возможность «не сломать всем всё». Из моей практики: в один из дальних уголков зоопарка завезли С++14 в прошлом году, до этого там был C++03. Всё скомпилировалось и стало работать чуть быстрее и эффективнее, примерно на 3%, эффективность по кэшам померить там сложно. После небольшого рефакторинга и вычистки кода получил прирост в тех краях в 21% по производительности.

Мне нравится Rust, но у себя (не в pet проекте) использовать я его буду очень не скоро ибо это очень большие риски для компании.

На C++ у меня есть проекты с кодовой базой в т. ч. по 15+ лет и они работают и потихоньку переписываются на свежее, благо, что С++20 уже везде поддерживается, за исключением нескольких мест в Embedded. Когда в конце 10х участвовал в разработке FlylinkDC++ там тоже были места родом ещё из середины 90х и это работало «из коробки».

Ну так какие гарантии, что комитет C++ внезапно не решит всё ломать? (:


Или этого не случится потому что противоречит здравому смыслу и никому не нужно? Ну так и с растом такая же ситуация.

Противоречит здравому смыслу — да, совсем никому не нужно — нет, недавно Google хотел всё сломать, до этого Facebook был. С Rust должно быть даже лучше чем с С++ ибо сразу есть модули и editions но есть тонкости поскольку editions на перспективу усложняют разработчикам компилятора жизнь. В общем я то только рад что системные и высокопроизводительные вещи можно теперь писать и на Rust тоже, но у себя я не потащил его в production даже в тех местах где уже пару лет как можно, пока только pet проекты.
Потому что это решение просто не пройдёт в комитете и его забанят :) Так как в комитете куча представителей абсолютно разных компаний с туевой хучей С++ кода, которые понимают цену поломке.

Как это отражается на дизайне языка — легко отследить по тем же модулям и спорам вокруг них.

Вон как модули завезли, то как я понимаю в С++ становится реально завезти механизм эпох (аналог Editions из Rust, за что им спасибо).
Вон как модули завезли, то как я понимаю в С++ становится реально завезти механизм эпох (аналог Editions из Rust, за что им спасибо).
Я надеялся на это, как на способ выхода из тупика… но пообщавшись с людьми, участвующими в стандартизации C++, выяснил, что они в этом направлении даже и не думают.
На тему эпох думают, но активно не обсуждают поскольку пока в сообществе не возникнет понимания как и для чего использовать даже те модули которые завезли в C++20 смысла в этом обсуждении мало.
Это хорошо :) Глядя на Rust пошло активнее и примеры в документе хорошие.

Собственно я потому и говорил про модули как про отправную точку. Без них было бы слишком больно.
Комитет C++ активно «блюдёт» возможность «не сломать всем всё».

Это на бумаге так.


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


Не забываем еще про двустороннюю совместимость редакций, когда крейт 2015 редакции может иметь зависимость крейта с редакцией 2018. Плюсам такой стабильности никогда не добиться.

Это на бумаге так.

А это разве не так?
Плюсам такой стабильности никогда не добиться.

А не добиться почему? Что мешает сделать это с потенциальным механизмом эпох на основе С++ модулей?
Я знаю, что ломают. Тезис был не в том, что не ломают, а в «Комитет C++ активно «блюдёт» возможность «не сломать всем всё».» Так что всё верно.
В C++30? Посмотрим.

Конечно посмотрим :)
Комитет C++ активно «блюдёт» возможность «не сломать всем всё

Простите, но чем это отличается от раста? С первой версии (вышла пять лет назад) у раста такой же подход.

Тем, что С++ блюдёт это на протяжении далеко не 5 лет. Вот и вся разница :) 5 лет это ничто, имхо.
because the lexer now eats <=> as a single token:
Видимо его личный гипотетический лексер, а не настоящий. В реальном мире это будет перевариваться не хуже чем такой побитовый сдвиг:
vector<vector<int>>
А, ну вот это уже лучше. Правда, еще надо бы найти реальный код, в котором sizeof используется без скобок.
С тем, что вложенные шаблоны парсеры в определенных случаях путали с побитовыми сдвигами, действительно одно время были проблемы, поэтому между угловыми скобочками было принято вставлять пробелы. Но это было починено, я как-то давно не сталкивался со случаями, когда приходилось бы вставлять пробел. Думаю, тут парсер тоже подкрутят на эту тему.
Не факт, ой не факт. В C++11 добавили правило, потому что эта коллизия всех задолбала, а главное — она случалась настолько часто, что все компиляторы её, на самом деле, поддерживали, сообщали об ошибке, но дальше компилировали, как ни в чём ни бывало (чтобы «наведённых ошибок» было поменьше). Поскольку код для поддержки уже реально было во всех компиляторах — его просто «узаконили». Коллизии с <=> встречаются настолько редко (буквально одна-две коллизии на миллион строк по исследованиям), что ни в компиляторах поддержки нет, ни в страндарте не будет, скорее всего.

Ну, поживём — увидим. Так-то да, коллизия очень редкая, но "для порядка" могут и починить.

Первый результат в каком смысле? Первое изменение, которое что-то ломает? Дак нет же. В C++20 круче есть: изменение, единственная цель которого — сломать уже существующий код:
struct Foo {
  Foo() = delete;
};

Foo foo = {};

Всё скомпилировалось

Вам повезло — вы писали на более чистом C++03 и не имели в кодовой базе невалидного кода, принимаемого более ранними компиляторами.

Вероятно так и есть, но везением это назвать сложно. Совсем древние места правили во Флае до меня наверняка.

Комитет, принимающий простые изменения по несколько лет ¯_(ツ)_/¯

Скорее всего не потребует. Rust специально проектировался так, чтобы можно было развивать язык, не ломая старый код. Уже сейчас сущестуют две редакции языка: Rust 2015 и Rust 2018. И вы спокойно можете использовать crate одной редакции с программой другой.

раст станет полноценной заменой с++

Он уже стал.

с++ разовьется достаточно чтобы смысла писать на расте не было…

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

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

А невозможно что именно? :) Вон С++ развивается семимильными шагами и новые фичи постоянно завозят. Так чего там невозможного то, а? Или так хочется, чтобы в С++ сломали обратную совместимость и конкурента точно убрали?
Он не стал

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

Так чего там невозможного то, а?

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

К счастью не стал. Интерес пусть будет. Я приложу все усилия, чтобы он только интерес и вызывал, а прод как писали так и продолжат писать на С++. Не знаю, черёд чего там настал.
Невозможно заставить компилятор ругаться на небезопасный код, потому что для С++ он является корректным. До тех пор, пока С++ на уровне семантики (читай стандарта) не начнет давать гарантии, безопасным он не станет.

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

Уже давно ходит шутка, что Rust это C++2050.

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


Так вот, что надо расту ещё развить? Можно перечень?

Ну тут много чего полезного, половины из этого перечня и в плюсах нет, значит ли это что на них нельзя писать пока не сделают (те же генерики, хоть higher-kind, хоть каких)?

половины из этого перечня и в плюсах нет

Какой половины? Из всего перечисленного в C++ нет разве что генераторов.

Ну в плюсах нет генериков, например (шаблоны это не генерики, как нам любезно подсказывает тот же msdn), значит нет и всех связанных с ними