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

Как так?

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

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

А вот и аргументация в стиле Ъ-фанатика подъехала. Чтоб ты понимал, например, в Swift, выражение:

10.1 as Int32

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

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

Да читал. Кстати вот ответ тебе если интересно:

https://pastebin.com/raw/ZxXiWkhJ

И объяснение для студентов:

https://pastebin.com/raw/sA8PYg71

Это не особенность языка, как в случае с сишкой.

и примеры:

https://godbolt.org/z/YbGXwo

https://godbolt.org/z/zGxQu9

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

В gsl есть narrow, есть не хватает проверки при инициализации

Все уже было в Симпсонах есть в boost. Но по факту С++ тут такой же кривой как и Rust. Можно долго с пеной у рта доказывать, что эти преобразования задокументированы, есть альтернативы и т.д., но по факту на лицо возможная потеря/порча данных при преобразовании. Причем непонятно, что мешало авторам Rust сделать такие преобразование сразу правильно, например, если человек хочет явно кастануть signed в unsigned и забить на проверки, то пусть делает это только в unsafe.

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

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

Хотелось бы, чтобы ТС продвинулся в познании Раста чуть дальше. Чтобы, так сказать, разоблачить Раст по-полной. Еды в девелопменте не хватает :).

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

Непонятно одно: зачем ты тут надрываешься и портянки текста производишь.

Решил поддержать единомышленника? У меня 200 сообщений, у тебя за 5000. Подумай сам, кто тут надрывается.

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

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

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

У меня 200 сообщени

Дата регистрации: 11.11.19

у тебя за 5000

Дата регистрации: 07.10.11

Не так уж и много за 9 лет. почти 2 сообщения в день. У тебя так же

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

Не так уж и много за 9 лет. почти 2 сообщения в день. У тебя так же

Ну он же сюда как на работу ходит. А, к примеру, предыдущее его сообщение это просто тупняк и мусор:

Объясните про аннотации типов сложных объектов в Python (комментарий)

П.С. посмотрел остальные комментарии, он просто агрессивный и малограмотный неадекват, в игнор.

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

Почитал про переполнение в расте, это цирк, В дебаге по дефолту падаем, в релизе не падаем. Какой гений проектирования это придумал.

А как бы ты сделал?

Вставлять проверки всегда и везде - замедлять код. Можно, конечно, сделать отдельные операции с разным поведением (и так и сделано), но всегда и везде использовать их будет неудобно. Вот и получается компромисс: проблему можно отловить на тестах, но и работает (в релизе) быстро.

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

если человек хочет явно кастануть signed в unsigned и забить на проверки, то пусть делает это только в unsafe.

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

Как по мне, ансейф тут не нужен, но преобразование через as сделано действительно не идеально. Но всё-таки прям всё и сразу предусмотреть маловероятно. Тут более показательно будет дальнейшее развитие языка. Если на as предупреждение будет выдавать, то отлично, проблемы не вижу. Впрочем, уже сейчас в клиппи есть пачка линтов на тему кастов. При желании можно вообще запретить as.

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

А как бы ты сделал?

Везде отключено по умолчанию. А так получается у языка разная семантика для дебага/релиза.

Вот и получается компромисс: проблему можно отловить на тестах, но и работает (в релизе) быстро.

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

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

Если на as предупреждение будет выдавать, то отлично, проблемы не вижу.

Если оно будет по умолчанию, согласен.

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

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

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

Получается тут и гарантий нет, и ложная иллюзия появляется, что язык что-то проверяет.

Ну так и про тесты без 100% покрытия сказать можно.

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

Ну я всё-таки считаю, что в данном случае это разумный компромисс.

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

среднестатистический погромист даже стандартные предупреждения компилятора игнорирует.

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

В защиту раста скажу, что клиппи - инструмент почти стандартный. Правда по умолчанию не все линты включены.

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

объяснение для студентов

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

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

Вставлять проверки всегда и везде - замедлять код

экхм, но ведь в расте именно так и делают, разве нет? При той же индексации массивов, например.

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

Чтение/запись за границами массива - это memory unsafety. Переполнение - нет.

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

экхм, но ведь в расте именно так и делают, разве нет? При той же индексации массивов, например.

Не совсем.

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

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

Ну и, наконец, если проверки во все числовые операции добавит, то это довольно серьёзным замедлением будет. А писать везде wrapping_add вместо + - будет сильным ударом по эргономике. Такой себе компромисс получается.

Вон в (старой) статье есть чуть больше подробностей об этом: https://huonw.github.io/blog/2016/04/myths-and-legends-about-integer-overflow-in-rust/

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

Вон в (старой) статье есть чуть больше подробностей об этом: https://huonw.github.io/blog/2016/04/myths-and-legends-about-integer-overflow-in-rust/

в этой статье прямым текстом написано

Another thing Rust misses compared to C is optimising x * 2 / 2 to just x, when x is signed

т.ч. замедление всех числовых операций «ради безопасности и большей стабильности» (c) в расте уже есть.

Ну и, наконец, если проверки во все числовые операции добавит, то это довольно серьёзным замедлением будет. А писать везде wrapping_add вместо + - будет сильным ударом по эргономике. Такой себе компромисс получается.

тогда почему там предлагают писать fadd_fast() и т.п.? Это не удар по эргономике? Раст преподносится с упором на безопасность, но вместо безопасности там в каждом углу такие вот компромиссы, баги, технический долг (сколько лет у них там было mem::uninitialized? А как насчет специализации разрекламированных в этой теме трейтов?) и неконсистентное поведение. По-моему его разработчики в принципе не понимают, чего хотят от языка.

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

можно менять определение когда выгодно

Историю изменений смотрел? И когда же стало выгодно?

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

т.ч. замедление всех числовых операций «ради безопасности и большей стабильности» (c) в расте уже есть

Хех. Да, x*2/2 придётся оптимизировать вручную.

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

т.ч. замедление всех числовых операций «ради безопасности и большей стабильности» (c) в расте уже есть.

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

В любом случае, что ты хочешь доказать? Раст не идеален? Тут я спорить не буду. Везде будет свой набор компромиссов.

тогда почему там предлагают писать fadd_fast()

Там - это где?

Раст преподносится с упором на безопасность, но вместо безопасности там в каждом углу такие вот компромиссы, баги, технический долг (сколько лет у них там было mem::uninitialized?

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

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

У меня 200 сообщений, у тебя за 5000. Подумай сам, кто тут надрывается.

Так ты поди без году неделя зареган, счетовод, лол. Дальше не читал — против аргументации, подкрепленной статистикой, мне нечего предложить 😆.

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

Не стоит пытаться достучаться до упоранта. @Naserral из таких.

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

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

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

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

Да читал. Кстати вот ответ тебе если интересно:

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

И объяснение для студентов:

Тут могу дать Царю ещё один совет. Смешной препод, которого не воспринимают всерьёз и потому которому не возражают, может этого не понимать, но вообще, перед тем как что-то объясняешь следует подумать о том, кому и зачем.

Если объясняешь тому, кто и так знает, то наверное не стоит время тратить. Если объясняешь тому, кто не знает, то надо объяснять так, чтоб поняли и поняли правильно. Особенно если объясняешь сектанту скриптухи, он ведь докопается до любой неточности. Вот конкретно в этом тексте Царь заявляет, что дженерики работают через vtable и тратит много времени на объяснение type erasure. Это неправда. Так дженерики работают только в Java и, в ограниченном числе случаев, в C# (параметр дженерика не должен быть структурой). Если в C# в качестве параметра передан value-type, то генерится собственный экземпляр. Когда дело касается Раста, то никакого vtable в дженериках там и в помине нет, vtable в Расте бывает только у функций, принимающих ссылку на трейт, тогда передаётся жирный указатель, состоящий из указателя на структурку и указателя на втейбл. В случае дженерика, естественно, никакой виртуальщины, честная инстанциация. Можно говорить о некотором аналоге еразуры только в отношении лайфтаймов, там да, если один раз вызвать функцию-дженерик для структуры со статическим лайфтаймом, а потом для такой же структуры в стеке, то вызовется одна функция. Но для всех комбинаций типов генерится собственный экземпляр, всё как в плюсах. Да и по-другому и быть не может, как запихать внутрь структуры другую структуру, не зная её размера? Аналогично с функциями, для создания переменных на стеке надо знать размер, надо знать, реализует ли конкретно этот тип Drop.

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

Момент, который я в прошлом ответе опустил, и потому Царь ещё не начал от этого отнекиваться - это критика веры Царя в пользу анализа тел функций. Он реально думает, что это достоинство плюсов, а не атавизм времён первых экспериментов «C с классами» через препроцессор. Дело в том, что, вопреки вере Царя, Раст - это не язык для лабораторок. По крайней мере при проектировании так считали. Авторы языка считали, что проекты на Расте будут крупными, будут жить и развиваться долго, и будут активно подключать сторонние библиотеки. Поэтому анализ тела функций прямо противопоказан, поэтому лайфтаймы и вынесены в сигнатуры функций и поэтому язык с отличным выводом типов внутри функции не добавил простейшую фичу вывода типа возвращаемого значения (точнее добавил в сильно ограниченном виде impl trait). В cигнатуре функции описывается полный контракт и язык не позволяет делать никаких поблажек на основании текущего кода в теле функции или вокруг места вызова. Идея в том, что пока контракт не меняли, всё должно быть работоспособно и не зависеть от обновлений библиотек или изменения собственного кода.

При написании лаб и курсовиков да, это мешает.

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

Ну в общем, судя по тому, как упорно Царь начал отмазываться от косяка с vtable, при этом не поддался на уговоры использовать нормальный термин «интерфейс», он реально думал, что там динамический вызов происходит и теперь боится признаться. Ещё и врёт, типа он говорил про «семантический vtable» при том, что это сочетание он составил, видимо, глядя на мой текст. Типа он не знает, что vtable - это описание реализации, а интерфейс - это общеупотребимый термин.

Ну ок. Дальше идёт пурга, где он пообещал разобрать потуги с атавистичными шаблонами в C++… но сделает это в другой раз.

Далее пошло обычное для идиотов нытьё про то, что на Расте только лабы пишут, что совершенно мимо кассы, пусть бы на нём вообще 1 единственную программу «хелло уорлд» написали бы, это никак не отменяло бы мотивацию проектировщиков языка. Думаю, даже такой необезображенный интеллектом чувак как Царь не станет отрицать, что авторы Раста мечтали о серьёзной разработке (про то что он уже не стану пугать беднягу).

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

Ну и про отсутствующий вывод типа:

use core::fmt::Debug;
use std::vec::Vec;
use std::convert::From;

fn foo<T:Debug>(bar: &T) {
    println!("bar == {:?}", &bar);
}

fn main() {
    // параметры дженерика выведутся
    let mut v1 = Vec::new(); // выводится тип v1 и v2, при том что справа от = тип неизвестен
    let mut v2 = Vec::new(); 
    v1.extend(
        (1..=5).map(
            |i|{
                v2.push(i); // автовывод типа v2  это Vec<i32>. Автоавывод из побочного эффекта замыкания!
                12.0 // автовывод возвращаемого значения f64 и, соответственно v1 Vec<f64>
            })
    );
    v2.extend(
        (10..=15).map(
            |i| {
                // v1.push(i); // нельзя запихать i32 в вектор с f64
                v1.push(From::from(i)); // но можно автоматически выбрать конвертер через имплементацию трейта
                  // From<i32> для f64
                i
            }
        )
    );
    foo(&v1); // тут можно переключить в отображение llvm-ir
    foo(&v2); // и убедиться, что это разные функции
    
    // v1 = v2 // ошибка. Чтоб глупый Царь не нёс пургу про то, что тут затирание параметра происходит
}

Конечно, бывают языки и с лучшим выводом типа, но это не C++ и ему подобные.

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

Вообще, самое грустное, что Царь вообще неспособен сопоставлять 2 своих утверждения, именно поэтому у него так подгорело, когда я показал, что его восхваления концептов в плюсах, если их поставить рядом, говорят о кривом дизайне языка. С темплейтами/дженериками та же фигня получается. Я объяснил ему, что авторы Раста не могли «не осилить» шаблоны как в плюсах, шаблоны из плюсов как раз самые простые в реализации, в Расте уже есть макросы, которые фактически делают то же самое. Царь увидел только слово макрос и завёл свою пластинку про недоязык, которому понадобились макросы. Он уже начисто забыл, что до этого ему не нравились нормальные дженерики с проверками типа и он топил за макроподобные.. даже не дженерики, а шаблоны из плюсов. Он реально не понимает проблемы, когда с одной стороны тело шаблона чуть ли не копипастится в исходник, авось соберётся, но при этом в объявлении 3 этажа из всякой enable_if.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Думаю, даже такой необезображенный интеллектом чувак как Царь не станет отрицать, что авторы Раста мечтали о серьёзной разработке

Наверное поэтому автор Раста ушел писать Swift.

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

Так будет просто добавлено ограничение и точно так же перестанет собираться, ничего не поменяется. Разве что будет более вменяемое сообщение об ошибке, что плюс, но не больше. Ну и говорить о серьезности, объемах и стабильности в случае Rust не приходится, т.к. он не умеет в то, что умеют все - в ABI. В С++ (C/Java/C#/etc.) можно собрать либу и отдать людям, а раст требует постоянной пересборки всего и вся.

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

умеют все - в ABI

В С++ (C/Java/C#/etc.) можно собрать либу и отдать людям, а раст требует постоянной пересборки всего и вся.

У C++ нет стабильного ABI.

RazrFalcon ★★★★★
()
Ответ на: комментарий от Serral
  1. https://wiki.gentoo.org/wiki/Upgrading_GCC#libstdc.2B.2B.so.6:_version_.60GLIBCXX_3.4.15.27_not_found
  2. А можно скачать Qt для MSVC и пытаться использовать его из mingw, но ничего не выйдет.
RazrFalcon ★★★★★
()
Последнее исправление: RazrFalcon (всего исправлений: 1)
Ответ на: комментарий от RazrFalcon

У C++ нет стабильного ABI.

https://itanium-cxx-abi.github.io/cxx-abi/abi.html

Можно скачать Qt и линковаться к нему хоть на CentOS, хоть на Ubuntu. При этом можно взять gcc, clang или icc.

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


https://wiki.gentoo.org/wiki/Upgrading_GCC#libstdc.2B.2B.so.6:version.60GLIBCXX_3.4.15.27_not_found

Так и с GLIBC та же история, и там же написано, что C++ ABI обратносовместимое.

А можно скачать Qt для MSVC и пытаться использовать его из mingw, но ничего не выйдет.

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

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

Прекрасно сработает.

Не сработает, слинковаться то оно слинукется, а в рантайме вылетит. Я из-за этого quickjs от гнусизмов чистил, чтоб в вижуале использовать.

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

Пруфца бы.

Это то, что я нашел и исправил:

#if defined(__x86_64__) || defined(__aarch64__)
#define JS_PTR64
#define JS_PTR64_DEF(a) a
#else
#define JS_PTR64_DEF(a)
#endif

#ifndef JS_PTR64
#define JS_NAN_BOXING
#endif

...

#elif defined(JS_NAN_BOXING)

typedef uint64_t JSValue;

...

#else /* !JS_NAN_BOXING */

typedef union JSValueUnion {
    int32_t int32;
    double float64;
    void *ptr;
} JSValueUnion;

typedef struct JSValue {
    JSValueUnion u;
    int64_t tag;
} JSValue;

Думаю ты поймешь. Но там есть еще и разные рантаймы, разные malloc/free, разные выравнивания могут быть и т.д. А еще на это могут влиять параметры компиляторов, которые могут еще и быть переопределены в коде. Опять же всякие директивы препроцессора. В общем на чем-то из этого оно продолжало валиться. Авторы библиотек в принципе могут стараться делать их совместимыми, но если на это изначально наплевали, то фиксить это после каждого обновления - сизифов труд.

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

Это всё замечательно, но ABI тут не при чём. Тем более аллокаторы.

Это все замечательно, но кто сказал, что ABI тут при чем?

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