Pull to refresh
37
3.5
Send message

Не хочется вас расстраивать, но это не так. Есть там и объект (сами объекты, конечно во время компиляции удаляются и остаются только внутренности), и дискриминант никуда не девается. Есть много крутых штук, вроде хранения дискриминанта в паддинге (и Option<bool> занимает столько же места, как и bool), но для обычного i32 впихнуть его некуда. Rust, конечно, крутой, но такое просто невозможно сделать безопасно. Для енумов без дискриминанта (и лишнего места) есть union, но его использование - unsafe.

например, что Result и Option занимают ровно столько памяти, сколько голые лежащие в них данные

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

А доклад мой, в чём, видимо и ирония :)

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

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

Вы прямо сейчас наверняка отвечали мне в браузере, написанном на C++, содержащем кучу UB

Технически это совсем не обязательно, 1 post запрос можно было бы и из Rust отправить (естественно я этого не делал).

Не программа?

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

Ну а если заниматься ещё и динамическим анализом вроде Address Sanitizer/Valgrind, то найдётся абсолютно всё

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

Если нет багов в unsafe-библиотеках, компиляторе, borrow checker...

А давайте без этого, в вышеупомянутом видео достаточно примеров багов C и C++ компиляторов, санитайзеров и прочего. Если так рассуждать, то и Python сразу unsafe, ведь в его реализации тоже баги могут быть. С таким подходом лучше сразу на кладбище ползти, там уже не до багов в коде будет. И довольно большая часть Rust'а так вообще формально верифицирована.

там полностью убраны проверки при разыменовании указателей

Нельзя убрать то, чего нет. Разыменование указателей это всегда unsafe операция, для safe кода гораздо чаще используются ссылки.

вопрос веры

Это не вопрос веры, это вопрос данных. И в Rust новые контрибьютеры делают в 70 раз меньше ошибок, чем в C++. Не на 70%, в 70 раз. Какая тут вера.

Буквально позавчера видел баг на Rust

А я сегодня видел пачку багов на C++, и что?

Люди пишут на Си и C++ с удовольствием и не парятся про какое-то там UB, несоответствие стандарту и прочая, прочая, прочая

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

rust отключит оптимизацию

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

Ну это же настоящий межплатформенный UB, на одной платформе получим одно, на другой - другое

А вот тут стоп, это очень важно. Далеко не каждое "плохое", "не очевидное", "странное", " вредное" и т.д. поведение является неопределенным. У вам вообще оксюморон получился, определенное (если на платформе А выполняется Х, а на платформе Б выполняется У, то поведение очень даже определено) неопределенное поведение. Это было бы platform dependent behavior (или implementation-defined behavior, я не уверен, я не программирую на C++). А еще есть unspecified behavior и compiler specific behavior. И это все разные сорта грабель на любой вкус и цвет. Про UB в комментариях под этой статьей много кто много чего полезного рассказал, можно их посмотреть. Еще в комментариях под моей статьей тоже много про это писали, там тоже можно много полезного узнать.

Да и разные инструкции процессору при разных обстоятельствах даже implementation-defined behavior, если компилятор вместо простого сложения чисел в цикле сразу на этапе компиляции это вычислит и оставит от функции только ret 100 это же не UB. С точки зрения программы это эквивалентно, результат то один и тот же.

добавить лишних инструкций на другой платформе

Опять же, не готов тут что-то сказать, понятия не имею что может быть на разных платформах. Нo в Rust числа не только оператором + складывать можно, есть еще пачка методов, типа checked_add, overflowing_add, saturating_add, unchecked_add, wrapping_add, wrapping_add_unsigned, а если этого мало, то есть еще интринсики, в которых (возможно, я не проверял) можно прям нужные инструкции +- напрямую использовать. Так что если хочется под конкретную платформу заоптимизироваться, то в этом никаких проблем нет.

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

А что, добавить в радиатор системы водяного охлаждения второй контур для чистой воды и можно не вставая из-за стола готовить себе чай, причем как раз пока что-то рендерится/вычисляется, делать все равно нечего, можно и чаю попить)

но в релизе тот же самый wrap around

Так в этом и проблема, что не "тот же самый". x + 1 < x в C и C++ не определено и компилятор может с чистой совестью весь код в соответствующей ветке if удалить (и не только удалить, программа с UB это вообще не программа и гарантированного поведения не имеет) т.к. он недостижим, ведь по стандарту переполнение - это ошибка и UB. В Rust же это как раз таки определено и компилятор такой фигни сделать не может. Т.е. оно может работать не так, как ожидалось и хотелось, но это не UB и можно на 100% понимать, что на самом деле произойдет.

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

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

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

Как определить Null pointer dereference

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

Словом, «И нашим, и вашим» — не получится

Вариант «ну что-то произойдет, может быть то, что тебе надо» точно работает очень плохо.

вряд ли ему следует лезть в C или Rust

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

Например, из языка C надо выкинуть операцию сложения

Можно же "просто" (понятное дело не в C, а вообще) определить переполнение и не использовать то, что переопределение не определено (т.к. оно определено) в оптимизациях. И все, проблемы (не все проблемы вселенной, а UB) заканчивается и жить становится сильно проще.

Что так можно, не значит, что так нужно

Так раз оно не нужно, то зачем оно можно?

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

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

Могу это подтвердить, сейчас пишу свой проект используя windows 7 (rustc 1.77.1 (7cf61ebde 2024-03-27)). Причем при компиляции используется не вышеупомянутый таргет, а обычный x86_64-pc-windows-msvc, из-за чего у меня в одной библиотеке не сработал cfg на этот таргет и ничего не работало.

Да и судя по этому комментарию все не так плохо.

антиэволюционным инстинктом делать дырки в стенах

А откуда вы знаете, может это у него брачные игры такие)

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

Аргумент увеличивает экспоненту повторов

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

DK = PBKDF2(PRF, Password, Salt, c, dkLen); c is the number of iterations desired

Да и даже если так, за 23 года это количество увеличилось на 2 порядка, увеличение на 1 явно не хватит на "ещё пару ближайших столетий".

Чтобы подбирать 1234, надо точно знать что там хотя бы одни цифры

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

Такие пароли небезопасны, потому что их надо где-то хранить, со всеми из этого вытекающими

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

PBKDF alike предоставляют аргумент степени повторов-итераций. Увеличьте его ещё на единицу, и можете спать спокойно ещё пару ближайших столетий!

За 20 лет в 600 раз увеличили

When the standard was written in the year 2000 the recommended minimum number of iterations was 1,000, but the parameter is intended to be increased over time as CPU speeds increase. A Kerberos standard in 2005 recommended 4,096 iterations; Apple reportedly used 2,000 for iOS 3, and 10,000 for iOS 4; while LastPass in 2011 used 5,000 iterations for JavaScript clients and 100,000 iterations for server-side hashing. In 2023, OWASP recommended to use 600,000 iterations for PBKDF2-HMAC-SHA256 and 210,000 for PBKDF2-HMAC-SHA512.

И если увеличивать его не с такой же скоростью, как растет скорость вычислений, то, соответственно, увеличится время хеширования. Думаю мало кому понравится ждать логина пару минут (а то и пару часов) чтобы его пароль 1234 был настолько же безопасен, как и kz~:1yIf0ES_s1oG'6Js.

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

Как раз скорость поиска очень даже ограничена (вычислительными мощностями всей планеты), а вот сложность пароля практически не ограничена. Сейчас будет сравнение апельсинов с карьерным самосвалом, но для увеличения скорости подбора в 2 раза надо либо в 2 раза больше железа (что дорого), либо ждать несколько лет пока индустрия выпустит новое, более мощное (или более эффективное в производительности за рубль) железо. А время подбора можно увеличить в n раз (n - размер словаря) просто добавив 1 символ. Что-то мне подсказывает, что сделать пароль чуть длиннее сильно проще.

1
23 ...

Information

Rating
809-th
Registered
Activity