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

Как так?

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

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

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

а также обозначь потенциальное ub если программа пытается запустить 40 млн тредов, или создать триллион об’ектов в памяти. это разве не UB?

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

Если как было записано изначально, то вообще не будет вызван ни dump_static ни dump_dynamic, всё будет заинлайнено в main.

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

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

Лоб в лоб.

static COUNT: AtomicU32 = AtomicU32::new(0);

struct Atom {
    name: Option<String>,
    guid: u32,
}

impl Default for Atom {
    fn default() -> Self {
        Self {
            name: None,
            guid: COUNT.fetch_add(1, Ordering::Relaxed),
        }
    }
}

impl Atom {
    fn set_name(&mut self, name: String) { self.name = Some(name) }
    fn guid(&self) -> u32 { self.guid }
    fn name(&self) -> Option<&str> { self.name.as_deref() 
}

#[derive(Default, Derefable)]
struct C1(#[deref(mutable)] Atom)

#[derive(Default, Derefable)]
struct C2(#[deref(mutable)] C1)

#[derive(Default, Derefable)]
struct C3(#[deref(mutable)] C2)

#[derive(Default, Derefable)]
struct C4(#[deref(mutable)] C3)
numas13
()
Ответ на: комментарий от numas13

Лоб в лоб.

итак из 9 строк на с++ получилось 26 на русте, на простейшем примере. вам не кажется что плюсы втрое выразительней оного?

а вашем случае можно написать эти две строчки?

C4 ll;
ll.setName("just a name");
alysnix ★★★
()
Ответ на: комментарий от alysnix

Если реализовать только реальную функциональность примера, то достаточно сделать что-то вроде

mod atom {
    use std::sync::atomic::{AtomicU64, Ordering};

    static COUNTER: AtomicU64 = AtomicU64::new(1);

    pub struct Atom {
        pub name: String,
        guid: u64,
    }
    
    impl Atom {
        pub fn new<T: Into<String>>(name: T) -> Self {
            Atom {
                name: name.into(),
                guid: COUNTER.fetch_add(1, Ordering::Relaxed),
            }
        }
        
        pub fn guid(&self) -> u64 {
            self.guid
        }
    }
}

Иерархия классов - средство для решения какой-то задачи, а не цель. В исходном примере не решается никакая задача.

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

Иерархия классов - средство для решения какой-то задачи, а не цель. В исходном примере не решается никакая задача.

там все готово для решения вот этой задачи:

C4 ll;
ll.setName("just a name");

и массы других.

alysnix ★★★
()
Ответ на: комментарий от numas13
let mut c4 = C4::default();
c4.set_name("just a name".to_string());

вот заболтали вы меня совсем. задача то была совсем другая! во какая задача была!

Atom* lp = new C4();
lp->setName("object of C4 class");

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

это точно компилируется? ссылка на С4 совместима со ссылкой на Atom? а почему? нет же наследования, насколько я понял. или есть наследование? с плюсах поинтер на атом и поинтер на с4 совместимы поскольку есть наследование. а тут как?

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

а тут как?

Лень листать выше, чтоб искать, что вы сравнивание, но в Rust есть так называемые fat pointers, т.е. это не просто указатель, а указатель + дополнительная информация.

Serral
()
Ответ на: комментарий от Serral
let mut atom: &mut Atom = &mut *C4::default();

почему ссылка на Atom оказалась тут совместимой с С4?

что вообще значит вот эта куета?

#[derive(Default, Derefable)]
struct C1(#[deref(mutable)] Atom)

#[derive(Default, Derefable)]
struct C2(#[deref(mutable)] C1)

#[derive(Default, Derefable)]
struct C3(#[deref(mutable)] C2)

#[derive(Default, Derefable)]
struct C4(#[deref(mutable)] C3)
alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от Serral

Лень листать выше, чтоб искать, что вы сравнивание, но в Rust есть так называемые fat pointers, т.е. это не просто указатель, а указатель + дополнительная информация.

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

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

что вообще значит вот эта куета?

Это чит использование сторонней библиотеки, чтоб уменьшить кол-во строк для примера. А в целом такой себе аналог смеси перегрузки оператора * и оператора T в С++, чтоб делать умные указатели.

https://doc.rust-lang.org/std/ops/trait.Deref.html

И там ЖИРНЫМ: «Deref should only be implemented for smart pointers to avoid confusion.». Т.е. это чисто синтетический пример, где и сам подход запрещен авторами Rust, и прикручена сторонняя библиотека.

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

Т.е. это чисто синтетический пример, где и сам подход запрещен авторами Rust, и прикручена сторонняя библиотека.

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

alysnix ★★★
()

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

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

что вообще значит вот эта куета?

Это чит использование сторонней библиотеки, чтоб уменьшить кол-во строк для примера.

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

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

Там нет использования «сторонней библиотеки».

лучше поясните, что значит этот мощный месседж? к чему эта куча буковок вместо простейшего «class C1:public Atom{}»

#[derive(Default, Derefable)]
struct C1(#[deref(mutable)] Atom)
alysnix ★★★
()
Ответ на: комментарий от alysnix

Это процедурные макросы, которые действительно избавляют от копипасты. В данном случае дописывают типам C* методы для дефолтной реализации и мутабельного разыменования (доступа к инстансу типа, который приводит к его изменению — записи в поля). Эта куча буковок позволяет использовать дефолтную реализацию типа Atom без реализации конструкторов для типов C*. А объяснять подробно мне лень, ибо долго расписывать.

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

Чувак, ты ведь вообще них*ра не знаешь про Rust, но всех убеждаешь, что он г*вно. Ты не из дурки нам сюда пишешь?

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

Т.е. это чисто синтетический пример, где и сам подход запрещен авторами Rust, и прикручена сторонняя библиотека.

И есть что-то правильное в том, что кривой антипатерн из плюсов реализуется кривым антипатерном из Раста.

Вообще, чего вы, фанаты плюсов не понимаете, что Раст делался вменяемыми людьми в 10х годах 21 века, через 30 лет после плюсов. Вы можете считать, что эти люди допустили ошибки, или даже что сделали совершенное говно вместо языка, но очень наивно думать, что они вот просто взяли и прозевали какую-то однозначно полезную фичу из плюсов. Нет. Они находились в выгодном положении, им не нужно было изобретать ООП/перегрузку, как плюсам, им не нужно было мимикрировать под плюсы как Java/D/C#, они могли себе позволить решать «воровать» вот эту конкретную фичу из плюсов или не надо исключительно с точки зрения её полезности и опираясь на опыт плюсов. И у них было дофига времени на обдумывание. Поэтому чувак с ЛОРА, будь он даже он трижды гением, за полчаса написания коммента, вряд ли найдёт реальную ошибку вот прямо так, на поверхности, сравнивая фичалист Раста и плюсов, гораздо вероятнее что эта отсутствующая фича будет сильно спорной и критикуемой уже на протяжении 30 лет.

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

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

Не понимаю, зачем Фэлкон и Хрюндель тратят время на этих срр неадекватов

Это Хрюндель-то адекват? O_o

Наоборот, это ООП в 99% нахрен не нужно, это идиотская идея из 80х, которая уже к концу 80х показала кучу присущих ей проблем и жила только на хайпе.

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

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

Вот конкретно проблема несовместимости инкапсуляции и наследования, например, широко известна с 1986 или 87 года

У чувака говно бурлит в башке, но т.к. он защищает Rust, то неадекватами объявляют не демагога Хрюнделя, а тех, кто с ним не согласен.

Ну а как иначе, если у самого Virtuos86 (по его же признанию) целью является закапывание плюсов. Хотя можно было бы заняться созданием чего-нибудь полезного на Rust-е.

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

Что вы несете? Там нет использования «сторонней библиотеки». Иначе покажите строку, где подключается эта библиотека.

А ты про нее у автора кода спроси, почему он ее «забыл». Вот она:

https://docs.rs/derefable/0.1.0/derefable/

П.С. адепты Rust не знают своего языка, это действительно позор.

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

адепты Rust не знают своего языка, это действительно позор

Никого не защищаю, но в случае C++ почти у всех точно так же :)

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

У чувака говно бурлит в башке

Можно подумать, что у многих приплюснутых в этом треде оно не бурлит? :)

целью является закапывание плюсов

Судя по высерам комментам тааких «ценителей цэпэпэ», как bonta или alysnix есть немало ушибленных, имеющих обратную цель (закопать Rust). Но про них вы что-то скромно молчите :)

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

И что интересно - как не запилят тред про Rust, так сразу «набигают» плюсовики и начинают хором петь про то что «рустнинужын!!!!!11». Если он такое г*вно, как вы его описываете, то зачем тратите своё время на подобные ср*чи? Ведь (следуя заветам дедушки Ленина eao197) «можно было бы заняться созданием чего-нибудь полезного на С++».

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

Можно подумать, что у многих приплюснутых в этом треде оно не бурлит? :)

Бурлит.

Судя по высерам комментам тааких «ценителей цэпэпэ», как bonta или alysnix есть немало ушибленных, имеющих обратную цель (закопать Rust).

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

Так что сейчас просто растофанатам прилетела ответка и они начали хныкать «А нас-то за что?»

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

Ведь (следуя заветам дедушки Ленина eao197) «можно было бы заняться созданием чего-нибудь полезного на С++».

Я не знаю в чей адрес этот выпад, но лично я Rust не закапываю. Более того, вот уже несколько лет придерживаюсь и озвучиваю вот такое мнение: если бы мне пришлось делать более-менее большой проект командой из нескольких десятков человек и с серьезными требованиями к надежности/безопасности (скажем, что-то торчащее в открытый Интернет), то я лично предпочел бы это делать на Rust-е, а не на плюсах.

Кроме того, как раз я тем и занимаюсь, что создаю что-то полезное на C++.

Так что если вы целились в меня, то не попали.

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

Никого не защищаю, но в случае C++ почти у всех точно так же :)

Это у всех так, язык не важен.

И что интересно - как не запилят тред про Rust, так сразу «набигают» плюсовики и начинают хором петь про то что «рустнинужын!!!!!11». Если он такое г*вно, как вы его описываете, то зачем тратите своё время на подобные ср*чи? Ведь (следуя заветам дедушки Ленина eao197) «можно было бы заняться созданием чего-нибудь полезного на С++».

Во-первых нужен. Во-вторых набигание взаимное, а данный тред изначально создан для холивара. В-третьих срач на ЛОР - это праздник. В-четвертых, занимаемся и создаем, и не только на С++, но иногда надо проветриваться и не только физически.

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

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

Если бы мне пришлось делать более-менее большой проект командой из нескольких десятков человек и с серьезными требованиями к надежности/безопасности (скажем, что-то торчащее в открытый Интернет), то я лично предпочел бы это делать на Rust-е, а не на плюсах.

Я б не рискнул брать Rust именно для задачи под несколько десятков человек. Он еще не устоялся, еще неизвестно как на нем писать большие проекты, и можно увязнуть как это произошло с servo, где в коммитах можно наблюдать директории layout_2020, чистку кода, рефакторинг, unsafe и много разного не связанного напрямую с реализацией самого servo, зато связанного с процессом разработки. Лучше уж даже Java.

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

В-третьих срач на ЛОР - это праздник

Дата регистрации: 11.11.19 09:16:39

Полугодовалый регистрант рассказывает про ЛОР, лол.

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

Ну а как иначе, если у самого Virtuos86 (по его же признанию) целью является закапывание плюсов. Хотя можно было бы заняться созданием чего-нибудь полезного на Rust-е.

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

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

Я б не рискнул брать Rust именно для задачи под несколько десятков человек.

А я бы рискнул.

Лучше уж даже Java.

Нет, в очередной раз проверять на практике утверждение «Java больше не тормозит» – это не мое.

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

Нет, в очередной раз проверять на практике утверждение «Java больше не тормозит» – это не мое.

Тормозит, но безопасна, удобна для разработки и имеет много батареек. Rust не тормозит, безопасен, но брать его для проекта - риск, да и не факт, что несколько десятков нанятых программистов не окажутся «экспертами» с ЛОР. Скорее даже так и будет. Ну и с батарейками печаль.

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

Этот субъект недавно выказывал свое «фи» в мой адрес как юзера ЛОР с многолетним стажем. Дескать, я хожу сюда, как «на работу». Признай он сейчас, что и он на ЛОР не первый год, это будет выглядеть каминг аутом :).

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

Этот субъект недавно выказывал свое «фи» в мой адрес как юзера ЛОР с многолетним стажем. Дескать, я хожу сюда, как «на работу». Признай он сейчас, что и он на ЛОР не первый год, это будет выглядеть каминг аутом :).

Я сказал, что ты здесь как на работе. А я делаю набеги раз в несколько лет.

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

О, пошли маневры.

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

Не затруднит предыдущий момент «набегаторства» обозначить? Юзернейм там, например.

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

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

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

Так что сейчас просто растофанатам прилетела ответка и они начали хныкать «А нас-то за что?»

Это-то понятно - одни дурачки фанатики воюют с другими. Старо как мир.

Я не знаю в чей адрес этот выпад, но лично я Rust не закапываю.

С вами как раз всё понятно (в хорошем смысле). Забавляют толпы «закапывателей», которые на своём любимом C++ сами не пишут, похоже.

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

срач на ЛОР - это праздник

наш человек :)

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

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

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

Нет, в очередной раз проверять на практике утверждение «Java больше не тормозит» – это не мое.

Томми, ты???

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

Вывод типов есть, нет шаблонных лямбд.

Не в лямбдах дело, можно все заменить на функции/структурки, а скобочки на метод, суть не поменяется.

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

а я думал, что говорю с интеллигентными людьми

(c)

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

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

можно было бы заняться созданием чего-нибудь полезного на С++

Так на плюсах уже всё написано (нет).

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