Pull to refresh

Comments 77

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

Я как понимаю, основная проблема в том что инструменты все еще новые, по сравнению с Unity, Godot, UE. Соответственно не хватает зрелости и много чего еще нужно руками делать. Но прогресс постепенно идёт

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

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

Тут в игру (pun intended!) вступает такой момент что движков вокруг уже полно и движок - это обычно штука которая не страдает от чрезмерного обилия багов после начального периода развития, так что сложно придумать вразумительную причину по которой нам очень-очень нужен движок именно на Rust. И наоборот, если какая-то компания берёт движок и допиливает его для нужд крупного AAA-проекта (как делали с Lumberyard например), им уже начнёт вставлять палки в колёса тот факт что быстро допиливать будет не так-то просто потому что Rust их бьёт по рукам а сроки горят и надо выкатывать игру уже вот-вот, а бизнес модель "пипл схавает, а краши поправим первым хотфиксом после релиза" реально работает и приносит деньги.

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

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

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

Но соглашусь, без конкретных примеоов это абстрактный спор)

Так ведь никто не создавал Rust с претензией, что он прямо на разработку игр заточен. С какой целью просить разработчиков\фанатов отверток признавать, что у отверток есть проблемы (ими трудно забивать гвозди)?

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

Но тут человек именно что гвозди отверткой забивать хочет всю статью. У него везде прослеживается мысль, что ему не нужна ни безопасность, ни надежность, а нужны быстрое прототипирование, хот релоад и "just get things done".

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

Всегда можно что-то придумать. Но кто этим должен заниматься за автора? У него 10 лет опыта иргостроения и несколько лет Раста. Сделал бы библиотеку упрощающую какие-то элементы разработки, пул реквесты в Bevy, придумал бы свои паттерны в конце концов.

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

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

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

Зачем писать поперек ветра и ловить хейт сообщества если можно убедить сообщество что с этими проблемами нужно что-то делать?

Это тоже важно.

Что за парадигма, критиковать Раст что-ли нельзя, святой он?

Здоровая критика всегда полезна. И её в посте автора действительно много (например время компиляции, orphan-rule в конечном приложении и много другого). Такая критика должна, по идее,привести к улучшениям в языке.

Но в тоже время есть критика неверно выбранного инструмента. Автор целый раздел назвал: "Rust being great at big refactorings solves a largely self-inflicted issues with the borrow checker", в то время как этот "Self-infliced issue" получился из-за несовпадения приоритетов о которых я уже писал.

Т.е. можно сколько угодно критиковать borrow-checker, но если он является краеугольным камнем языка - это не конструктивно, т.к. он никуда не денется. Можно лишь частично его улучшить, но до определенного предела. Прийдется с ним жить.

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

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

Моё имхо, пытаться писать на расте (да даже на чистых плюсах) скрипты для игры, мазохизм, на расте можно и я думаю это будет вполне даже удобно, писать внутренности движка, а скриптовать на quirrel, lua, haxe, да хоть на том же nim, если уж очень хочется что то скомпилировать.

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

И здесь возникает интересный психологический момент - есть хоть один игровой движок на Rust, который поддерживает отдельный скриптовый язык для игровой логики вроде C-sharp в Unity и Godot, GDScript в Godot и так далее? У меня сложилось впечатление, что сообщество настолько уверенно в иедеальности Rust, что и скрипты предлагает на нем писать. Могу ошибаться, детально все движки на Rust не изучал.

UFO just landed and posted this here

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

Справедливости ради, veloren геймплейно уныл чуть более чем полностью и является клоном древней cube world.

Что доказывает т.з. автора - переписать существующее? Пожалуйста! Загеймдизайнить что-то интересное? Нет!

Несколько лет пишу на расте, подтверждаю все сказаное. Делать R&D задачи на расте, где конечная цель не определена - больно и долго. В одном проекте несколько тысяч RPC и добавить 2 новые структуры занимает 10-20 минут, с учетом времени работы rust-analyzer, cargo check и пересборки проекта.

Скажите, а есть ли задачи, в которых писать на Rust приятно?

Тут даже не в задаче дело.

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

Если же вам важен именно продукт - быстро выкатывать новые фичи, экспериментировать и т.п. - вряд ли вы оцените Rust.

Тип задачи может лишь сгладить ситуацию. Чем более задача типовая - тем протореннее будет дорожка. Например, вряд ли у вас возникнут проблемы с каким-нибудь REST API.

Конечно. Вот, например: https://blog.cloudflare.com/introducing-oxy

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

PS. Я работаю в их конкуренте. Наш аналог сделан на плюсах, и как ни украшай C++ ленточками, а всё равно рога торчат.

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

Через час этот прототип уже на свалке окажется и то что где-то там в будущем можно было прийти к конфликту с типами никто не узнает.

Деплой в прод лучше не называть выбрасыванием на свалку... Даже если по-факту так и есть )

Ситуация с GUI в Rust просто ужасна

Как и везде, окромя C# и Delphi

Есть идея десктопного пет-проекта - настольное приложение для заметок (ибо перепробовал уже больше десятка и все кривые). Соотвественно требование для GUI-фреймворка - поддержка основных платформ включая Linux и наличие качественного и бесплатного компонента визуального редактора текста. Можете посоветовать что-то на C-sharp (решетку редактор сьедает)? Ни MAUI ни даже десктопный Blazor насколько мне известно с Linux не дружат. Даже если убрать требование наличия компонента редактора остается одна Avalonia, но для такого приложения это ключевой компонент. Соответственно вижу только один вариант - веб-интерфейс с Electron или что-то вроде Tauri на Rust кстати.

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

А в каком виде редактор текста интересует? Что от него требоваться будет?

Не совсем понял вопроса. Если по возможностям - то визуальное редактирование, НЕ markdown, шрифты, картинки все в таком духе. Особое требование - нормальная работа с буфером обмена, ибо по итогам работы с программами заметок с ней везде проблемы - где-то картинку в тексте растянет и добавит огромные поля вверх и вниз, где-то в абзаце текста вставит переход на новую строку/абзац после каждой строки в оригинале. Опять же нормальное копирование в буфер обмена форматированного текста и простого текста, не markdown исходника (как минимум по умолчанию). Для веба нашел Quill, TipTap (демо базового редактора) и еще парочку.

Ну, если говорить о Delphi, то для такого подойдёт пакет HTML Components. Там своя реализация HTML рендера и полный контроль над управлением содержимым. Вставлять можно что угодно, управлять содержимым как нужно ну и сохранять/загружать в удобном формате (или в html).

Кроссплатформа будет доступна, привязок к внешним библиотекам нет. Так что можно за 3-4 вечера соорудить клиент-серверное решение, например, используя RESTfull сервер на MARS, с авторизацией на JWT и серваком под Linux/ Windows.

Ну и выглядеть будет как любой современный веб-сервис, если нужно. Кроссплатформенный GUI фреймворк (FMX) работает на GPU.

Спасибо. Вряд ли я буду изучать Delphi, в карьерном плане Csharp (с ним и работал ранее) и даже Rust выглядят перспективней. Но по комментариям в разных записях технологически создается впечатление что Delphi во многом более зрелый чем более популярные технологии и языки.

Кстати а какая лицензия сейчас у Delphi и упомянутых фреймворков? Я написал бесплатный но по факту конечно важная открытость, а не бесплатность как таковая.

Компилятор закрытый. Что в свою очередь говорит о том, что существует только одна IDE для этого языка. И, соответственно, для коммерческой разработки, IDE не бесплатная.

Это, всё, пожалуй, можно охарактеризовать как "не очень хорошо". Но, в России есть поставщики, и можно без проблем приобрести. Для не коммерческой разработки IDE бесплатная и имеет свою (Community) редакцию с небольшими ограничениями. При этом RTL (рантайм библиотеки) и поставляемые два GUI фреймворка (VCL и FMX) имеют "открытые исходники", т.е. мы можем в момент разработки получить к ним доступ, прочитать и даже частично изменить под себя или что-то исправить. IDE очень гибкая и имеет обширный API для плагинов, которые могут позволить встроить новые механизмы в IDE, например, Co-pilot или GPT, управлять проектом или сборкой и т.д. Открытость RTL позволяет более подробно изучить доступные методы и классы (помимо отдельной документации и встроенной в код документации), в частности понять "как работает" или "как реализовано". Т.е. штатно, библиотеками мы можем очень сильно повлиять на то, как работает язык, например, реализовать смартпоинтеры или аналог "defer" из языка Zig (недавно такой делал). Ну и существует открытая Jira для пользователей IDE, где можно завести баг или новую фичу и в течение какого-то времени получить ответ и возможно решение в грядущем патче (баги обычно правят от 3 до 4 месяцев, а фичи сильно по-разному).

Из минусов ещё то, что IDE (и компиляторы) на данный момент, может работать только под Windows. Хотя, с переходом на стандартизированный LSP, мы можем использовать, например, VS Code для написания кода. Но без дизайнеров, все же, это не сильно полезно.

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

Не понятна жалоба автора на конфликты доступа к одним и тем же объектам во время выполнения. Он бы предпочёл вместо этого вместо panic! тихое похеривание данных?

double borrow не гарантирует, что будет "похеривание" данных

Не гарантирует, но может к нему привести, при чём очень вероятно. Именно поэтому вся суть языка Rust сводится к тому, чтобы такого не допускать.

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

Автор почему-то думает, что в однопоточном коде он может безопасно лазить в глобальный стейт как хочет и ему ничего за это не будет. Хотя обратный пример "начал править стейт, вызвал функцию, в ней коллега ВНЕЗАПНО добавил чтение этого полуразобраного стейта" вполне тривиален.

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

Rust неудобный и некачественный язык. Разработка на нём не уменьшает количество ошибок при увеличении времени разработки раз в 5 и ухудшения читаемости кода.

Тот же современный C++ намного более безопасный, удобный и быстрый во всех смыслах язык. Одно только правило "не больше 1 изменяемой ссылки на объект" - страшная тупость. Для этого правила нет никаких логических и разумных причин. Это как правило "не больше 1 грязной кружки в квартире" И не важно сколько людей хотят пить, 1 или 10 и как удобнее их мыть - по 1 или по 10 за раз.

Одно только правило "не больше 1 изменяемой ссылки на объект" - страшная тупость. Для этого правила нет никаких логических и разумных причин

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

Ну да, это как выкинуть из дома все ножи и вилки чтобы нечайно не воткнуть их себе в глаз :) Для тупых это сделано, нормальные умные программисты и так никогда такого не сделают, плюс sanitizer-ы сразу покажут проблему, или тесты на худой конец...
За 29 лет опыта программирования я такой глупости не совершал ни разу, поэтому для меня Rust - язык для идиотов :)

плюс sanitizer-ы сразу покажут проблему, или тесты на худой конец...

Ну то есть проблема таки есть, просто отлавливается внешними силами, а не самим компилятором

нормальные умные программисты

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

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

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

Вы определитесь, пожалуйста: или https://habr.com/ru/articles/758566/comments/#comment_25935352

Основное правило программирования - код должен быть понятен даже идиоту и даже идиоты должны быть способны его поддерживать.

или Rust ужасный язык, потому что для идиотов.

Оба сразу - нельзя.

Тут нет противоречий. Код должен быть ПОНЯТЕН даже идиоту, а Rust из-за своих тупых ограничения понять в разы сложнее, чем тот же C++.
Rust для программистов-идиотов, к тем, кто код читает и понимает это не относится.
Программисты-идиоты с идиотскими ограничениями языка физически не могут сделать код понятным. Куча семантического сахара, решения специфичные только для Rust, из-за которых приходится адаптировать алгоритмы... Даже в статье приводили примеры библиотек, что нарушают принципы Rust но от этого более понятные, удобные и приятные в работе... Если принципы языка вредят принципу "понятен даже для идиотов", то язык плохой.

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

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

Ну, если уж такой разговор зашёл, то в любых более или менее сложных проектах на C++ есть и code style conventions, и проверки формата которые не дадут ничего смёржить пока clang-tidy чем-то недоволен, и документация по проекту где есть соглашения о том в какие дебри забредать не надо, и ревьюверы которые не дадут увлечься шаблонной уличной магией. :)

Меня персонально всегда смущал путь Rust на концептуальном уровне. Большинство современных языков стремится сделать написание корректного кода проще. Rust стремится сделать написание некорректного кода сложнее - казалось бы похоже но, как говорят в Одессе, две большие разницы.

Да, всё это есть, и полгода занимает переключиться с стиля/формата/ревьюеров на предыдущем месте работы на новые. В примерно одинаковых проектах в двух биг-тек компаниях одни фигачат сервера на корутинах и вообще полный C++20, в другой сплошные коллбэки и исключения отключены по историческим причинам.

Две разницы объясняются тем, что одни языки придуманы оптимистами: "давайте дадим программистам удобные инструменты и они будут писать прекрасные программы", а другие - пессимистами: "если этим волю дать, они случайно или намеренно, но таких чудес наворотят". Я за вторых, я слишком хорошо себя знаю.

То, что вы описали - дело 5 минут переключения. Достаточно посмотреть на пару файлов из проекта и уже можно писать так как нужно.
Главное чтобы принципы были непротиворечивыми.

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

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

Вы явно не писали давно на современном C++. Сейчас код практически неотличим от того же TypeScript / JS / PHP.
Единый стиль форматирования - выбор человека, отформатировать можно всё как угодно, да и есть ClangFormat например, а у CLion великолепный форматтер и без clang.

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

Ещё добавлю, что вы написали "сложный проект". Сложный по какой метрике? Если по тому, насколько сложно читать код, то получается что так и есть. Но это не проблема и вина C++, а вина архитектора проекта.
А вот проекты сложные по количеству сущностей, например, или количеству связей между ними прекрасно можно сделать так, что читать код будет легко, просто и даже приятно. Просто нужен архитектор с опытом и мозгами :)

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

Но могу согласиться, что иногда компилятор слишком сильно опекает.

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

Я вам больше скажу, сейчас нет ни одной задачи, которую можно быстрее, красивее и эффективнее решить с помощью Rust нежели с помощью C++26.

Единственный плюс Rust в унификации и каталогизации библиотек.

разработаны в формате фреймворков

Мне кажется, что выборка специфическая. Я не придираюсь, скорее любопытно. Можно список, скажем, из десяти таких библиотек? По моему, это справедливо для веб-фреймворков, но зачем иметь несколько в одной кодовой базе? Ещё можно про асинхронные рантаймы и то практически все используют токио и не парятся.

Десятка не назову, подтвержу вашу догадку про веб, и асинк рантаймы. Но вдобавок в вебе например бывают ещё и дополнительные разные инструменты, например крейт tonic, для осуществления связи по gRPC не отдаёт наружу никаких очевидных методов общения с программой. Он принуждает либо писать реализацию внутри рантайма, либо лепить костыли с пробрасыванием каналов внутрь. UI фреймворк iced, так же не откажется выступить скелетом программы (хотя с ним попроще вроде как, и если сильно захотеть, то можно всё таки реализовать и свой рантайм и ивент луп и подписки).

GUI в расте нормально (в продакшене) не щупал, поэтому спорить не буду. Хотя мне кажется, что GUI в целом чаще в виде фреймворков реализован. Ну а касательно тоника - коммуникация через каналы кажется вполне себе прямым способом, а не костылём.

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

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

И дело даже не в изменении, а в хранении двух ссылок на объект в разных местах.

Что вам мешает написать алгоритм через unsafe, и формально его верифицировать и выставить наружу безопасный API? Ведь это как-раз задача для умного программиста.

А что вам мешает надевать штаны через голову? Но надеваете то вы их через ноги... Если использовать unsafe, то Rust лишается своего единственного плюса... И зачем он тогда вообще нужен?
Не бывает безопасного/надёжного на 99% кода, код либо надежный и безопасный, либо нет, так же как вы либо живы либо мертвы, но не живы на 90% :)
Поэтому unsafe блоки в коде делают его весь ненадёжным и проще уж тогда на C++ писать :)

Похоже вы из моего комментария прочитали только слово unsafe.

Формально верифицированный алгоритм будет на 100% надежен, и абсолютно без разницы сколько там unsafe, на С++ написан или на Rust.

Не бывает безопасного/надёжного на 99% кода, код либо надежный и
безопасный, либо нет, так же как вы либо живы либо мертвы, но не живы на
90% :)
Поэтому unsafe блоки в коде делают его весь ненадёжным и проще уж тогда на C++ писать :)

А как тогда работают другие языки? Ведь все они под капотом вызывают API ОС и код зависимостей на C, что по определению не безопасно. Вот только в Java, Go или C-Sharp что-то не слышно про ошибки с памятью и UB.

Так что таким подходом вы отрицаете саму идею безопасного API и разделения ответственности между авторами библиотек.

Не совсем так.
1. Даже плохой unsafe блок, хотя бы помечен в коде.
2. Даже плохой unsafe блок либо повалит программу в ошибку, либо испортит какое то значение локально, не приводя к общему UB программы.
3. unsafe по сути даёт не так уж много. Не убирая проверок с остального.

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

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

Другой вопрос, что сам список UB намного, просто в десятки раз меньше чем в С++. Ну и п.1 и п.3 сильно помогают.

Тоже не совсем согласен.

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

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

В целом скорее наверно вкусовщина. Но на мой взгляд, у раста компилятор поступает честнее.

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

А вот разработчики Rust считают по-другому (и я их полностью поддерживаю):

unsafe only means that avoiding undefined behavior is on the programmer; it does not change anything about the fact that Rust programs must never cause undefined behavior.

https://doc.rust-lang.org/reference/behavior-considered-undefined.html

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

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

Нет, он может сделать с этим кодом что угодно, в т.ч. потому что Rust компилятор это фронтенд к LLVM.
Кроме того описанное вами поведение нигде не гарантируется в документации, и я не представляю как вы пришли к такому выводу.

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

Согласитесь же, что компилятор либо не должен в принципе съедать и компилировать некорректную программу, пытаясь UB избежать и приводя к непредсказуемому поведению, исходя из того, что к UB программа точно прийти не должна, мол программист полюбому это учёл, либо должен съедать и компилировать - что забрал, то и отдал.

И тем не менее компилятор Rust иногда размазывает UB по всей программе:
https://hyphenos.io/blog/2023/debugging-ub-unsafe-rust-code/
А вот позиция одного из разработчиков Rust, почему UB это необходимое зло: https://www.ralfj.de/blog/2021/11/18/ub-good-idea.html

Итак я привел вам:
- теорию
- документацию
- реальные примеры
- и даже позицию авторов языка

Вы же пока привели только рассуждения.

Итак я привел вам:

- теорию

- документацию

- реальные примеры

- и даже позицию авторов языка

Вы же пока привели только рассуждения.

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

unsafe only means that avoiding undefined behavior is on the programmer; it does not change anything about the fact that Rust programs must never cause undefined behavior.

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

И тем не менее компилятор Rust иногда размазывает UB по всей программе:https://hyphenos.io/blog/2023/debugging-ub-unsafe-rust-code/

Хм.. Ну вообще я бы не сказал, что тут UB размазано, оно происходит весь внутри одного большого unsafe блока в функции sctp_sendmsg_internal да и я бы это не UB назвал бы а скорее Unspecified Results

А вот позиция одного из разработчиков Rust, почему UB это необходимое зло: https://www.ralfj.de/blog/2021/11/18/ub-good-idea.html

А тут, первый пример, я бы вообще назвал скорее прямым и очень даже Specified и Defined обещанием компилятору.
А вот момент с double &mut я бы действительно назвал UB.

В целом возможное размазывание я увидел скорее в комментарии разработчика по UB как раз. Ну и всё же, в компиляторе раста из ссылки второй видно, что компилятор не размазывает UB безразбору, а старается размазывать только те, которые как ни странно Defined, для этого =). И то, полагаю, что компилятор просто транслитит это в UB для LLVM, который соответственно и вырезает код с UB из конечной программы.

В целом то, я и не пытался что то доказать, я не отрицал на 100%, что в компилятор не может в каком то кейсе размазать UB по программе, будь то специально или будь это просто багом, который если зарепортить пофиксят. Я скорее говорил о том, что rust старается этого не делать как раз, и локализировать ub внутри unsafe блоков, а выпускать наружу лишь Unspecified Results

что компилятор в принципе не имеет понятия UB

Не помню тут ли писали или к другой статье, насчет поведения +, что у раста переполнение в дебаге это trap, а в релизе wrap around (я подозреваю на проверяемой платформе).
Я сам не проверял, но если это так, то понятие UB должно быть. Иначе как сделать я просто не представляю, иначе дефайненый wrap around начнет сильно замедлять код на определенных архитектурах.
Если это все так, то поведение + по сути не отличается от clang со включенным ubsan в дебаге.

Придумал хороший пример: вызов в unsafe функции https://doc.rust-lang.org/std/ptr/fn.write.html по не выровненному указателю. В зависимости от архитектуры, данные могут записаться совсем не туда, куда вы ожидаете. И пошло-поехало..
И заметьте, всё это без оптимизаций, а только из-за того что компилятор поверил программисту в unsafe.

"не больше 1 изменяемой ссылки на объект" - страшная тупость

Это что, вон в хаскеле вообще нет изменяемых переменных в обычном виде. Там для того чтобы завести изменяемое значение люди целые монады городят! Ну тупыыые.

Ну да, поэтому посмотрите на популярность Haskell... :)
Вы ещё brainfuck приведите как пример :)

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

Sign up to leave a comment.

Articles