А unsafe можно даже не проверять руками. Есть #[deny(unsafe_code)]
Это типичный подход манагеров. Запретить, расставить в шеренгу в 9:47, ни минутой раньше или позже, и чтобы все пели гимн КНДР 13 минут. Особо отбитые даже предлагали сделать опцию «запрещать использование unsafe до явной директивы разрешения ее в блоке»:
Разработка на расте и так не сахар, а ее хотят вообще в концлагерь превратить. Впрочем, так планктону и надо, не хватает только надзирателя с плеткой, который будет хлестать за невыполненный план потребления смузи.
Попытка расшарить между потоками мутабельные данные (ссылками или Arс’ами) без синхронизации даст ошибку компиляции
Не даст, потому что программист напишет «unsafe {...}» или дернет кривую библиотеку, которая реализована через unsafe, примерно как через этот unsafe реализована стандартная библиотека. Это ты сейчас такой невозмутимый и уверенный в библиотеках, потому что под раст кроме стандартной библиотеки толком ничего и нет. А что начнется, когда попрут массово с гитхаба писанные индусами поделки?
Это должен делать аллокатор, а не вектор. Вектор должен быть типизирован аллокатором и наследовать от него safe/unsafe.
Хотя в терминологии раста даже статические аллокаторы будут unsafe.
Да нет никакого смысла, как и в самом атрибуте unsafe. Конечно unsafe. Только в Java нет нотации для safe/unsafe и Java не декларирует memory safety на главной странице
Смысл этого safe, как в питоне или жаве, заключается в том, что в режиме safe можно было бы посадить писать индуса за миску риса, и иметь хотя бы какие-то минимальные гарантии, что этот индус не угробит тебе проект.
Правда, гарантии самые минимальные, потому что Rust абсолютно никак не защищает от паники, дедлока, гонок, ну и тем более от ошибок логики. На самом деле единственное, от чего защищает Rust — это от индусов, которые прикрывают кривой код тряпочкой, будто его нет вовсе, будто и не он его писал. Я хочу еще раз вспомнить цитаты из этого треда:
Ещё один момент - safe код на Rust удобно использовать в многопотоке. Сколько времени я потратил, читая исходники в Java, пытаясь выяснить, можно ли какой-нибудь DocumentBuilderFactory шарить в тредах безопасно - не счесть
Попытка расшарить между потоками мутабельные данные (ссылками или Arс’ами) без синхронизации даст ошибку компиляции
То есть, легионер рад был бы избегать использования непотокобезопасных типов в потоках, но он тупо не знает, что там потокобезопасно, а что — нет. Это поведение ответственного кодера. Дай ему четкие описания того, что потокобезопасно — и он будет этим описаниям следовать. Это делается в C++. Да, в нем нельзя насильно заставить писать многопоточку только на потокобезопасных типах, но грамотному кодеру это и не нужно.
red75prim же описывает поведение какого-то саботажника, который только и ищет способа, как бы внести в приложение багу. Проблема в том, что багу он таки внесет, потому что Rust никак не повышает надежности работы приложения — он только позволяет избежать UB. А теперь сами себе ответьте на вопрос: стоит ли вступать в эту тоталитарную секту safe кода только для того, чтобы ваш код перестал быть UB, а вместо этого четко и ожидаемо валился с паникой или вешался в дедлоке?
Кому вообще такое «преимущество» может быть полезно? Браузер, и то не весь, потому что там есть части целиком состоящие из unsafe, вроде движка JS или DOM. Какой-нибудь ответственный серверный софт, принимающий запросы из интернета, но без состояния, потому что БД опять-таки подразумевают сплошной unsafe. В принципе, есть какая-то проприетарная колоночная СУБД, в которой скриптинг делается на расте, но он очень ограничен и сама БД писана не на расте. Всё, всем остальным оно не нужно, потому что им нужно работающее приложение и нет угрозы удаленного доступа — им глубоко плевать, умерла ли их система из-за UB, из-за паники, или из-за деделока — это один и тот же результат, и потому для них разницы между C++ и Rust нет никакой.
С++: Нормалёк, буду следить за джуном, чтобы херни не напорол. Rust: автоматически контролируем работу джуна. AAA! Концлагерь, всё пропало! Показательно
С++: следили за джуном. Но все равно БД лежит.
Rust: автоматически контролировали работу джуна. Но все равно БД лежит.
у меня rustc компилился и того дольше, часа 3-4 (на рязани 5 3500U + ~6гб озу), в один момент снес и заменил rustc-bin, над еще попробовать выпилить из системы его полностью
В C# оно используется когда упираются в производительность, но ещё пытаются усидеть в рамках байт-кода. В основном, такие попытки безуспешны и лучше подключить сишную библиотеку. Но, возможно, кого-то небольшой прирост по скорости и спасает. Я же подозреваю, что и в C# этот режим не нужен.
Если я правильно понимаю, то в Расте unsafe не для скорости, а для преодоления недостаточной гибкости safe.
Ну и непонятно почему ты противопоставляешь использование unsafe и сишные библиотеки?
Зачем учить особенности safe, unsafe и Си? Можно учить две сущности вместо трёх. Если только боязнь хейтеров, которые будут говорить, что 80% растовских проектов на Си написаны. Зато ведь растовская часть будет абсолютно безопасна.
Зависит от цели. Если мы не хотим помнить особенности всех разновидностей конструкторов и деструкторов, то да, надо ломать совместимость. Если мы просто хотим отладочный режим без UB и исключениями с выводом stack trace как в Питоне во всех библиотечных функциях, то переделок будет не так много. Будут не поломки совместимости, а уменьшение скорости в отладочном режиме.
Ну то есть memory safety никакой нет, а safe rust безопасен ровно настолько, насколько безопасна unsafe прослойка под ним, и держится на честном слове.
Смотри, объясняю на пальцах. Есть проекты, выполняющие идентичную работу, один на Си, один на Раст, в каждом по 10к строк. В проекте на Раст 20 строк с unsafe, то есть, если писать идиоматичный код, в проекте будет 20 или чуть больше строк, которые могут вызвать ошибки, не проверяемые на стадии компиляции. В Си-версии проекта таких строк будет 10к. Ну хорошо, несколько меньше, опустим комментарии. Но ты же не будешь спорить, что шанс поймать ошибку в 0.2% кода и шанс поймать ошибку в почти 100% кода - это разные ситуации?
Прямо вспомнился тот древний анекдот про блондинку: " - Какой шанс, что мимо нас сейчас пробежит динозавр? - 50%! - Как так?! - Ну, или пробежит, или не пробежит!"
Тут надо уточнение. Так будет если мы в каждой строчке используем адресную арифметику, хитроумное преобразование типов, а также производим выделение и освобождение памяти в куче.
В проекте на Раст 20 строк с unsafe, то есть, если писать идиоматичный код, в проекте будет 20 или чуть больше строк, которые могут вызвать ошибки, не проверяемые на стадии компиляции.
Программа, в которой нет unsafe, ничего не делает. Если в программе на 10к строк всего 20 строк unsafe, то она либо катастрофически бесполезна, либо является клеем между библиотеками, в которых осуществляется вся работа.
Клей можно писать на любом языке, раст же пытается претендовать на место С и С++.
Но ты же не будешь спорить, что шанс поймать ошибку в 0.2% кода и шанс поймать ошибку в почти 100% кода - это разные ситуации?
Для начала прекрати популизм и сразу обозначь, что речь идет исключительно про ошибки работы с памятью. Придерживаясь достаточно краткого набора правил, ошибки работы с памятью в С легко избежать.
Далее, несмотря на заявляемый зерокост, растовый safe дорог. Вместо безопасности И скорости получается «безопасность» ИЛИ скорость – достаточно взглянуть на «идиоматичный» код на расте на benchmarksgame. Когда раст оказывается в нише С и С++, приятный и легко читаемый язык превращается в нечитабельные портянки.
Ну да, но в Раст надо ещё придумать ситуацию, когда такой код нужен, а в Си он на каждом шагу.
Вот придумай реальную, часто используемую ситуацию в Раст, когда такие конструкции нужны.
адресную арифметику
Есть в Раст, но слайсы делают её практически бессмысленной.
хитроумное преобразование типов
Да, Раст всячески ограждает от таких преобразований, хотя и существует transmute. В любом случае, есть простое и безопасное приведение, а остальные аналоги всяких плюсовых dynamic_cast решаются более безопасными методами.
выделение и освобождение памяти в куче
Это максимально оптимизировано. Хотя можно и вручную. Опять же, мне не приходит идея, как это использовать. Своя реализация аллокатора? Какие ещё идеи?
В любом случае, есть простое и безопасное приведение
Не ври, в расте нет приведения типов. Есть дырявый каст as (что там, кстати, про safety рассказывалось?) и небезопасный transmute. Отдельно можно упомянуть deref/into, которые приведением считать сложно и которые пишутся явно.
а остальные аналоги всяких плюсовых dynamic_cast решаются более безопасными методами.
Какие аналоги, какими безопасными методами, конкретику в студию.
Есть в Раст, но слайсы делают её практически бессмысленной.
Какое отношение слайсы имеют к адресной арифметике?
всяких плюсовых dynamic_cast решаются более безопасными методами.
Нет наследования – нечего решать. Безопасность превыше всего.
выделение и освобождение памяти в куче
Это максимально оптимизировано. Хотя можно и вручную. Опять же, мне не приходит идея, как это использовать. Своя реализация аллокатора? Какие ещё идеи?
Программа, в которой нет unsafe, ничего не делает.
Воцарилось недопонимание. В программе из 10к строк ты можешь 99% времени писать, не заботясь о переполнениях, освобождениях памяти, 100500 целочисленных типах, переданных без всяких гарантий ссылках, убогих строках, и вот этим всем легаси. А двадцать раз в проекте выделить загончик для разыменования сырого указателя или небезопасного приведения.
Да тупо Раст удобнее. Сишники/плюсовики так каждый раз млеют от мысли о едином репозитарии и универсальной системе сборки. Но от crates/cargo их прямо корчит. Про нормальные современные строки я молчу. Вообще после темы строк сишникам залезть бы под шконку и сидеть, голоса не подавать.
Задам практический вопрос с позиции рядового разработчика. А в расте есть что-нибудь похожее на Qt? Чтобы я, не особо вникая в устройство фреймворка и параллельно читая книжку, смог за неделю родить приличное GUI приложение?
А без батареек, язык широкой массе программистов не нужен. В этом плане С++, java, C# просто вне конкуренции. Это как на мерседесе ездить по России, машина хорошая, спору нет, но если до ближайшего сервиса 200 км, она не нужна.
а safe rust безопасен ровно настолько, насколько безопасна unsafe прослойка под ним
Не согласен. Опровергается тем что в итоге под ним машинные коды. Но код явно безопаснее сферических машинных кодов написанных руками. Компилятор может создавать безопасность достаточного уровня поверх небезопасного уровня - вообще-то это его работа.
Разница между абсолютно условными «опасным» и «безопасным» - методы доказательства корректности. В безопасном - компилятор. В опасном - «тут три строчки кода, очевидно это безопасно, вот три абзаца комментов объясняющих почему». И втрой метод работает отлично в таких случаях. Можно кричать «врети», но я наверное предложу аксиому о которой совершенно не буду выступать в дискуссию - можно доказать что три (условно) простых строчки кода безопасны без особых средств. Хочешь поспорить - лучше с кем-то другим
Компилятор может создавать безопасность достаточного уровня поверх небезопасного уровня
Ничего он не может создавать.
В unsafe можно нарушать любые инварианты, и компилятор будет считать, что они корректны.
В safe раст ничего сделать нельзя, он защищает от самых идиотских ошибок, связывая руки.
Не кажется, что в модели не хватает золотой середины?
Вы сами признали, что вектор – unsafe. Я с вами согласен. Теперь вопрос: язык предоставляет заявленную гарантию memory safety? Предлагаю ответить в контексте упомянутых as и молча переполняющейся арифметики.
Предлагаю ответить в контексте упомянутых as и молча переполняющейся арифметики.
В сях и плюсах это создаёт проблемы с безопасностью доступа к памяти из-за непроверяемого по умолчанию индекса при доступе к массивам и это, гм, фича (развязанные руки, простреленные ноги и т.п.). В safe расте не создаёт, а если создаёт - то это баг и будет исправлен. Что тут сложного?
Я правильно понимаю, что переполняющаяся арифметика и некорректные касты в С/С++ – плохо и создает проблемы, а в расте – нормально, и проблем не создает?
В плюсах тоже куча safety фич - автоматически вызываемые деструкторы, RAII, итераторы. Но нету других.
Rust делали позже, учли ещё пару опытом наработанных фейлов и их исправили. Суть криков всех дедов лишь в том что что-то не как в плюсах и им непривычно. Приняв решение срать на Rust, потом они подыщут удобные аргументы для поддержки своей позиции.