LINUX.ORG.RU

Rust и типобезопасность

 ,


3

7

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

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

Почитав документацию:

The as keyword does safe casting

Набросал такой примерчик:

fn main() {
        let a: f64 = std::f64::MAX;  // данное значение просто пример "большого числа"
        let b = a as i64;
        println!("{}", b);
}

Вопросы:

1) С какой стати это вообще компилируется?

2) Да, f64 и i64 нужно одно и то же количество битов для хранения значения, ну и что?

3) Почему результат меняет знак?

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

Как так?

★★★★★
Ответ на: комментарий от htower_

Полностью C/C++ он вряд ли заменит, но свою нишу займёт, я думаю.

Да, займет он нишу языка для написания хелловорлдов и обсуждения на форумах, на этом собственно и все.

Разорванный Флакон

anonymous
()
Ответ на: комментарий от anonymous

такие люди, как он, неучи

Эдик как программист - неуч, причём агрессивный. Про остальные его способности ничего не знаю (он, вроде, в науке работает).

я обычный Флакон

разорванный?

htower_ ★★
()
Ответ на: комментарий от anonymous

Про Эдика нам хоть что-то известно

Ага. И этого достаточно.

anonymous
()
Ответ на: комментарий от anonymous

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

bonta ★★★★★
()
Ответ на: комментарий от htower_

Эдик как программист - неуч, причём агрессивный.

Ну, его код я видел, а твой – нет, только попытки выставить себя умнее.

разорванный?

Да, @RazrFalcon

anonymous
()
Ответ на: комментарий от anonymous

только попытки выставить себя умнее.

Завидуешь? У тебя-то даже эти попытки - фэйл за фэйлом.

anonymous
()
Ответ на: комментарий от Serral

С++ слишком сложен

и чем дальше - тем хуже :( Наплодили столько, что чёрт ногу сломит

https://habr.com/ru/company/jugru/blog/469465

Им надо начать дропать легаси, иначе язык совсем необъятным станет. Но на это вряд ли пойдут :(

Rust тоже не образец очевидности

Ну по сравнению с плюсами - пока вполне очевидный :)

htower_ ★★
()
Ответ на: комментарий от anonymous

Завидуешь?

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

anonymous
()
Ответ на: комментарий от Serral

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

Но зато если изучить яп которые сложные - то код станет проще (когда знаешь яп). Ну как говорят лингвисты - чем меньше словарный запас - тем больше человек должен сказать слов чтобы донести смысл - так же и с Си vs любой другой язык который появился после него.

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

bonta ★★★★★
()
Ответ на: комментарий от andalevor

Важно отличие Rust от С в том

C? Кто сказал «C»? Тема с C и C++ тут побочная. Мой поинт был про безопасный супер современный ЯП, который не позволит выстрелить себе в ногу, если не использовать unsafe, а не про бажный копролит C и совместимый с ним C++. А получается, что те же самые грабли, на которых наступали 25 лет назад и в этом современном ЯП наступаются так же удобно, как и раньше, и даже еще удобнее, т.к. нет никаких внешних признаков, что что-то пошло не так.

Хотя тут уже написали, что это баг, и что надо брать какую-то найтли версию и использовать saturation arithmetic. Или что вообще данная фича as - баг в дизайне языка.

seiken ★★★★★
() автор топика
Ответ на: комментарий от anonymous

попытки выставить себя умнее

Вы не правы :) К Эдику у меня претензия ровно одна - он осилил С на каком-то уровне (молодец) и решил, что он теперь «илитарий». Он поливает грязью всё, что не стыкуется с его (узкой) картиной мира, например знаменитый «нинужный хрюникод», ведь, как известно, КОИ-8 хватит всем :) В общем, мои претензии не к скиллам Эдика, а к его регулярной буйности/невменяемости поведения.

htower_ ★★
()
Ответ на: комментарий от htower_

кстати я эту статью с большим удовольствием прочитал. Без шуток.

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

Это я к тому что эта статья может новичков спугнуть, но на самом деле, на практике проблем нет, теория порой страшнее практики, в Си++ :) имхо.

bonta ★★★★★
()
Ответ на: комментарий от seiken

Хотя тут уже написали, что это баг, и что надо брать какую-то найтли версию и использовать saturation arithmetic. Или что вообще данная фича as - баг в дизайне языка.

В nightly с saturation arithmetic просто будет выводить:

9223372036854775807

а не отрицательное число…

Так же без предупреждений и прочего…

fsb4000 ★★★★★
()
Ответ на: комментарий от htower_

Вы не правы :)

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

anonymous
()
Ответ на: комментарий от bonta

Вот эти 100500 вариантов поведения (неочевидных зачатую) и вымораживают. Причём с каждым новым стандартом их всё больше и рекомендации меняются. Особенно весело тем, кто пилит несколько проектов с разными версиями этих самых стандартов. В одном случае так надо делать, в другом - иначе. Потому народ и разбегается с плюсов на всякие Go/Rust/Swift/…

htower_ ★★
()
Ответ на: комментарий от anonymous

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

Ну не только же у Царя могут быть поклонники/подражатели :)

htower_ ★★
()
Ответ на: комментарий от seiken

C? Кто сказал «C»? Тема с C и C++ тут побочная. Мой поинт был про безопасный супер современный ЯП

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

Разорванный Флакон

anonymous
()
Ответ на: комментарий от htower_

ну вот как я понял в новых версиях cтандартов обещается быть чуть проще в вопросах инициализации :)

bonta ★★★★★
()
Ответ на: комментарий от htower_

Ну по сравнению с плюсами - пока вполне очевидный :)

Есть опыт? Или это «гадание по фотографии»?

Serral
()
Ответ на: комментарий от htower_

Меня особо впечатлило, как Саттер в своем выступлении более получаса (!) рассказывал, как правильно передать параметр в функцию.

Для не пишущих на C++ звучит как анекдот, а нам не смешно :(

anonymous
()
Ответ на: комментарий от anonymous

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

Это, правда, не считая смартпойнтеров (на это у Саттера еще полчаса, наверно), и без учета примитивных типов. Всё вместе - и так же дохрена «если – то» наберется.

anonymous
()
Ответ на: комментарий от anonymous

Я тоже тот видос смотрел. Там он ещё вначале говорил про число программистов на С++, и что несмотря на все крики про смерть и сложность С++, число программистов растёт с каждым годом, и график показывал…

https://youtu.be/qx22oxlQmKc

fsb4000 ★★★★★
()
Последнее исправление: fsb4000 (всего исправлений: 1)
Ответ на: комментарий от fsb4000

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

Я, кстати, про это видео: https://www.youtube.com/watch?v=xnqTKD8uD64

anonymous
()
Ответ на: комментарий от RazrFalcon

Раст в десятки раз проще C++. Этого достаточно.

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

Serral
()
Ответ на: комментарий от bonta

Линус тоже свалился, он хороший эксперт в своей области, хорошо знает Си, но на Плюсах он даже ничего не писали и вряд ли их понимает, но имеет своё авторитетное мнение например :)

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

Lrrr ★★★★★
()
Ответ на: комментарий от Lrrr

ну Торвальдса можно понять. Он фактически embedded-программист

Да ну?! Линус всегда был системным программистом, а системное программирование != встраиваемому. И Линукс он писал как нечто UNIX-like и как ОС чисто для персоналки, обычного компа без какой-либо встраивальщины. Писюк на i386 и была вся система, и никуда она не встраивалась. Это потом, на волне нездорового ажиотажа вокруг Linux, этот сгусток копролитических идей из 70-80гг. стали пихать куда ни попадя, в т.ч. и во встраиваемые системы.

а в этой области кресты не котируют по куче причин.

ну назови хоть одну

seiken ★★★★★
() автор топика
Последнее исправление: seiken (всего исправлений: 1)
Ответ на: комментарий от RazrFalcon

Специализации ещё нет. О чём вы?

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

Serral
()
Последнее исправление: Serral (всего исправлений: 1)
Ответ на: комментарий от seiken

ну назови хоть одну

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

anonymous
()
Ответ на: комментарий от anonymous

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

Это ответ на какой-то другой вопрос. Речь шла о:

embedded-программист, а в этой области кресты не котируют по куче причин

Embedded, Карл.

seiken ★★★★★
() автор топика
Ответ на: комментарий от RazrFalcon

Раст в десятки раз проще C++. Этого достаточно.

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

anonymous
()
Ответ на: комментарий от RazrFalcon

А, так вы ещё что-то донести пытались, но соррян, не углядел.

Кажется с юмором у нас у обоих не очень.

Serral
()
Ответ на: комментарий от RazrFalcon

В C++ сначала происходит инстанциирование, а затем компиляция.

Компиляция не имеет к теме никакого отношения.

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

Неверно. В расте не существует такого понятия как инстанцирование. И никакие трейты не проверяются.

В расте аннотируются трейтами сигнатуры, а далее функция проверяется.

Из-за чего ошибки в шаблонном коде намного более вменяемые.

Нету в расте шаблонного кода. Эксперт не разбирается в вопросе. Раст просто не тайпчекает типы аргументов на входе. Тайпчекается одна сигнатура, с одним типом. Это не шаблон.

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

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

<source>:6:34:   required from 'void max_value(auto:11&&) [with auto:11 = MyType [3]]'

<source>:10:40:   required from here

/opt/compiler-explorer/gcc-trunk-20200327/include/c++/10.0.1/bits/predefined_ops.h:43:23: error: no match for 'operator<' (operand types are 'MyType' and 'MyType')

   43 |       { return *__it1 < *__it2; }

А что же это? А где же «не влезет»? Неужели эксперт врёт? https://godbolt.org/z/gnJ_ot

Ну а теперь чудо. Мы берём и заменяем тип на тип имеющий данный оператор: https://godbolt.org/z/wsXVtp и всё работает. А вот в расте нет. Почему?

Потому что С++ может в тайпчекер, а раст нет. Такие дела.

erevan
()
Ответ на: комментарий от htower_

Это, конечно, здорово. Но осталось подождать лет 10 и можно будет юзать эти расты в коде за пределами своей личной «песочницы».

erevan
()
Ответ на: комментарий от RazrFalcon

Остальное - это что? Это не ошибки. Это контекст. То, что в твоём изваянии контекст не осилили - это не уменьшение ошибки. Контекст можно вырубить. И опять же, то что тебе об этом не рассказали - это твоя проблема. Проблема твоей полной несостоятельности.

erevan
()
Ответ на: комментарий от red75prim

Чего для раста такое не требуешь? Почему твои потуги не собираются другими раст-компиляторами? Почему не собираются старыми версиями? Объясняйся, не убегай как обычно.

erevan
()
Ответ на: комментарий от htower_

И много народу сидит на раста? Я недавно «откатывал» свой код до не-раст варианта, т.к. на одной из систем, где считать пришлось (выч. кластер), стоит CentOS 7.3.1611 без раста. И обновлять эту систему будут примерно через бесконечность :(

Методичку почини. Не позорься так.

erevan
()
Ответ на: комментарий от htower_

Разница только в том, что Rust на ту же центось ставится в одну команду, а свежий gcc надо руками конпелять.

Есть тысячи говносборок подобным говносборкам раста. Как гцц так и шланга. К тому же ты настолько опозорился, что сел в лужу даже с центос7 - https://copr.fedorainfracloud.org/coprs/jwakely/gcc-latest/ - первая ссылка в гугле.

Латай методичку.

erevan
()
Ответ на: комментарий от RazrFalcon

Баланда в 10 раз проще еды. Ты сделал свой выбор. Срать под себя в десятки раз проще. Ты сделал свой выбор. Вернее выбора то у тебя нет.

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

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

erevan
()
Ответ на: комментарий от anonymous

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

++

intelfx ★★★★★
()
Ответ на: комментарий от erevan

Давай о примерах. Касательно «не влезет» аргумент так себе, там действительно приличная простыня. Затем,

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

Если в С++ ты в шаблонную функцию, использующую <, подставишь int, как ты сделал в том примере, то конечно она заработает. Если MyType, то конечно она не заработает, ведь у MyType не реализован оператор <. Минус такого подхода заключается в следующем:

  • Необходимо знать, что лежит в потрохах этой функции, чтобы не получать неожиданные ошибки.

  • В общем случае ты не можешь гарантировать, что оператор <, даже если он реализован у конкретного типа, реализует отношение строгого порядка. Это может быть частичный порядок, может быть вообще что-то иное.

В Rust эти проблемы решаются следующим образом: ты требуешь от типа реализации необходимых трейтов. Пример с int провалится не потому, что у int не реализовано отношение строгого порядка, а потому, что сама функция некорректна. Прочитай сообщение об ошибке внимательнее, функция обобщенного аргумента &[T] не может реализовать max потому, что сферический T в вакууме не реализует Ord, а именно сферический T в вакууме ты и получаешь на входе. Аналогично с Debug: ты не можешь напечатать обобщенный аргумент типа T потому, что T не реализует Ord. Даже если ты подашь на вход какой-то конкретный тип, который будет реализовывать используемый трейт, функция все равно будет некорректной, ее корректность не зависит от аргумента на входе. Использование функции не требует знания ее потрохов – ее сигнатура уже сообщает тебе все, что нужно.

Если ты сделаешь

struct MyType(i32);

fn max_value<T: Ord + Debug>(items: &[T]) {
    println!("{:?}", items.iter().max());
}

fn main() {
    max_value(&[MyType(1), MyType(2), MyType(3)]);
}

, то функция окажется корректной, а подстановка туда MyType – нет, ведь MyType не реализует Ord. Такая версия уже будет работать с int и любым другим элементом класса типов Ord и Debug.

Итого, либо ты не понял, о чем говорил @RazrFalcon, либо ты принципиально не понимаешь, как работает такая система типов. Такой вот царь.

Siborgium ★★★★★
()
Последнее исправление: Siborgium (всего исправлений: 1)
Ответ на: комментарий от Siborgium

Итого, либо ты не понял, о чем говорил @RazrFalcon, либо ты принципиально не понимаешь, как работает такая система типов.

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

Virtuos86 ★★★★★
()
Ответ на: комментарий от Siborgium

Использование функции не требует знания ее потрохов – ее сигнатура уже сообщает тебе все, что нужно.

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

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

В любом случае, твои потуги так же ничего не стоят и потому, что «использование» - никого не интересует. Потому как при использовании никого не интересуют твои говнотрейты. Всё сводится к тому - собралось/не собралось.

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

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

Но, если мы возьмём требования посложнее - ты тут же обделаешься. Во-первых тупо потому, что ты никогда не напишешь код эквивалентный С++. Твоё недоязычок слишком слаб. А там, где ты его напишешь - у тебя будет сигнатура на пол экрана. Приватные трейты, генерик-трейты, сигнатуры говнофункций. Хотя в целом код на твоём недоязычке максимально примитивен и шансов реализовать что-то уровня С++ ты не сможешь в 999 случаев из тысячи.

anonymous
()
Ответ на: комментарий от Siborgium

В Rust эти проблемы решаются следующим образом: ты требуешь от типа реализации необходимых трейтов.

@Siborgium, @dave, @RazrFalcon

Дак в итоге, С++20 разрешил ваши претензии или нет?

В С++20, ты тоже можешь требовать от типа реализации необходимых концептов(трейтов), и С++ не будет заглядывать внутрь функции(пытаться инстанциировать)…

https://godbolt.org/z/ewtxkX

Ошибки:

https://godbolt.org/z/Yka52P (если не реализована печать)

https://godbolt.org/z/rdKFNW (если не реализовано сравнение)

Плохо разве что тем, что довольно мало встроенных концептов:

https://en.cppreference.com/w/cpp/concepts

Ну и то что поддерживается пока лишь двумя компиляторами: gcc 10 и VS 2019:

https://imgur.com/a/cj9cx8F

https://en.cppreference.com/w/cpp/compiler_support

http://libcxx.llvm.org/cxx2a_status.html

fsb4000 ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.