LINUX.ORG.RU

Rust 1.21

 


4

5

Состоялся релиз языка системного программирования Rust.

Итак, новшества:

  • Теперь можно использовать статические ссылки для литералов (для размещения значений в статичной памяти (куче), вместо слотов стека).
  • Перед блоком «<>» теперь можно вставлять разделитель "::":
        my_macro!(Vec‹i32›::new); // Так нужно было писать раньше.
        my_macro!(Vec::‹i32›::new); // Раньше этот код считался некорректным.
    
  • Библиотека jemmaloc обновлена.
  • LLVM теперь может запускаться параллельно с трансляцией при компиляции с несколькими юнитами (-Ccodegen-units=N) генератора кода, изменение позволило сильно сократить потребление памяти во время сборки.
  • Стабилизированы API std::mem::discriminant, needs_drop и итератор for_each.
  • Добавлено много новой документации.
  • Можно установить RLS (Rust Language Server, серверный модуль для IDE с поддержкой протокола LSP) при помощи команды rustup (rustup component add rls-preview).
  • В cargo (пакетный менеджер для Rust) появилась возможность установки нескольких пакетов одновременно.

>>> Подробности



Проверено: jollheef ()
Последнее исправление: cetjs2 (всего исправлений: 8)
Ответ на: комментарий от Esper

Смотря чем компилировать.

Какая разница? Есть же стандарт.

Код вполне себе C (без плюсов). Отсюда и вывод.

char buf[256] = {0};

Само по себе это точно не сработает.

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

Да и зачем забивать нулями целиком, когда можна

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

где обявление s? Какого оно размера? sizeof(s) < sizeof(buf), > или == ?

А тут какая разница?

Ну нифига себе... Лови SEGFAULT!
sizeof(s) < sizeof(buf), а копирование идёт по длине buf. Учитывая, что последний - буффер, его размер выставляется с запасом. Так что, такая ситуация будет очень часто возникать! Ну и словит strncpy segfault на выходе за область памяти s.
Код бывает всякий, вонючий и не очень...

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

А вот тут не заметили неверный порядок аргументов.

s всё равно, скорее всего, константное, так что пусть компилятор за меня замечает.

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

Код вполне себе C (без плюсов).

И что?

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

Причём тут это? Оно не сработает, потому что, если strlen(s) >= 256, то все твои нули перезапишутся и buf не будет null-terminated.

словит strncpy segfault на выходе за область памяти s

С чего он за неё выйдет? Он дойдёт до нуля, и после этого перестанет трогать s и начнёт фигачить нули в buf. Это ж не memcpy. А то, что s - null-terminated, вроде как, подразумевается.

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

buf[sizeof(buf) - 1] = 0;

sizeof(buf) == 0 , buf[-1] = 0 ... Угу...
А всё потому, что не char buf[256], а char buf[MAXPATH] или любой другой дефайн, завязанный на версию компилятора. Нет, ну понятно, что этот дефайн не должен быть нулёвым никогда, но мало ли?

strncpy(s, buf, sizeof(buf) - 1);

А вот тут не заметили неверный порядок аргументов.

А он совсем не обязательно неверный. Может в примере кода опущен этап заполнения буфера.
Тут бы вообще делать так:

strncpy(s, buf, min(sizeof(s),sizeof(buf)) - 1);
А по скольку размеры могут определяться на этапе исполнения, то проще забить нулями строку — это надёжно.
Мне такой код, написанный «СИ»-шниками в 1997 году, на глаза каждый день попадается. Приколы там бывают с той ещё издёвкой над программистами.

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

s всё равно, скорее всего, константное, так что пусть компилятор за меня замечает.

Не факт. Оно может прилететь из другой библиотеки через API, а там сам рогатый не разберёт, кто и что присылает.

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

И что?

Натыкался на случай, когда цикличная инициализация массивов не поддерживается от слова «совсем». И запись в конце вида " = {0}" вызывает ошибку компиляции.

Оно не сработает, потому что, если strlen(s) >= 256, то все твои нули перезапишутся и buf не будет null-terminated.

=__=

Учитывая, что последний - буффер, его размер выставляется с запасом.

А иначе уже надо делать так:

char * buf = new char[sizeof(s) + 1];
buf[sizeof(buf) - 1] = 0;
strncpy(buf, s, sizeof(s) - 1);
И хорошо бы не хвататься за strlen как за утюг голыми руками. Чай не факт, что всегда в коде будет применяться char, а не wchar_t какой-нибудь. Юникод на дворе ж.

Он дойдёт до нуля, и после этого перестанет трогать s и начнёт фигачить нули в buf. Это ж не memcpy.

Читать в начале поста. Да, попадались кривые компиляторы. Привет с оборонки.

А то, что s - null-terminated, вроде как, подразумевается.

Эх... Я даже не буду рассказывать... Просто поверь) Привык защищаться.

krotozer
()
Ответ на: Так от anonymous

Раст говно, Ada - вот где сила!

Читаю сейчас забавный комикс про Аду и Бэббиджа (Сидни Падуа). Забавна ассоциация.

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

sizeof(buf) == 0 , buf[-1] = 0

Тогда этот код, скорее всего, сольётся и в твоём варианте.

char buf[0] = {0};
strncpy(buf, s, sizeof(buf) - 1); // strncpy(buf, s, SIZE_MAX), ага

Может в примере кода опущен этап заполнения буфера.

Притянуто за уши.

strncpy(s, buf, min(sizeof(s),sizeof(buf)) - 1);

Но зачем?

А по скольку размеры могут определяться на этапе исполнения

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

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

Натыкался на случай, когда цикличная инициализация массивов не поддерживается от слова «совсем»

Выкидывай на мороз.

=__=

Я такого не понимаю, пешы словами.

А иначе уже надо делать так

Если максимальный размер s известен и есть возможность аллокации, можно заюзать обычный strlen или memmove.

И хорошо бы не хвататься за strlen как за утюг голыми руками. Чай не факт, что всегда в коде будет применяться char, а не wchar_t

Если там wchar_t, то компилятор и не даст схватиться.

Да, попадались кривые компиляторы.

В смысле, с нестандартным strncpy? Чё тогда не написать свой?

Привет с оборонки.

Понял, почему ракеты падают.

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

x/0 всё также ub?

Если x - целочисленное, то паника в рантайме (с выдачей предупреждения при компиляции о попытке деления не ноль), если же дробное — не скомпилируется (попытка деления целого числа на дробное).

Вполне себе defined behavior.

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

Вполне себе defined behavior.

где и как это определено?

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

Выкидывай на мороз.

Мечтаю об этом! Но оно до сих пор ещё стоит на отдельных рабочих станциях по разным закоулкам страны.

Если максимальный размер s известен и есть возможность аллокации, можно заюзать обычный strlen или memmove.

Что можно, то можно, конечно. Хотя сейчас стараюсь переводить работу в коде на std::string. Если его корректно использовать, то он удобен, а 14 лишних байт, если не имею дела с моделью данных, погоды не делают.

В смысле, с нестандартным strncpy? Чё тогда не написать свой?

А в итоге так и написал. Потом выпилил, ибо тот самый компилятор уже отправился в небытие. И слава Богу! Но в коде местами ещё встречаются конструкции с проверками. Продукт огромен, кода много.

Понял, почему ракеты падают.

Они падают не потому. Программеры могут писать по актуальным стандартам, но действует правило неразглашения и сертификации для ДСП. А потому наваяна куча «инопланетного» кода. Разработчики из разных отделов не могут напрямую лезть в дела друг друга, что уж говорить об институтах. Эта замшелость, конечно, в печёнках сидит. Но всегда найдётся безопасник, что будет гнуть свою линию. И ладно бы мы использовали свои компиляторы, свои ОС, свои IDE и.т.д., но используются-то модификаты.

Но могу обрадовать: если какое-то оборонное предприятие прогорает, но на его бывших сотрудниках вырастает другое, а там сразу пишут с нуля, уже без таких приколов. Этот процесс всё ещё продолжается. Последствия 90-ых слишком затянулись...

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

АлгТД

Забавно, впервые вижу, чтобы кто-то так сокращал ADT

посмотрите, что такое АлгТД в википедии

Щас бы к Википедии апеллировать. Ок, посмотрел, нашёл Rust в списке Programming languages with algebraic data types. Что сказать-то хотел, чем enum не сумма?

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

АлгТД

Забавно, впервые вижу, чтобы кто-то так сокращал ADT

Ну что ж, с почином! Это чтобы не путать с АТД

посмотрите, что такое АлгТД в википедии

Щас бы к Википедии апеллировать. Ок, посмотрел, нашёл Rust в списке Programming languages with algebraic data types.

В этом же списке и C++ есть, что множит его ценность на 0.

Что сказать-то хотел, чем enum не сумма?

Не поддерживает индуктивные типы.

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

что множит его ценность на 0.

Так зачем же тогда туда отправлять?

Не поддерживает индуктивные типы.

Зато поддерживает value-types, что, очевидно, для системного языка необходимо. Да и если уж теоретически занудствовать, рекурсивные не типы то чтобы «не поддерживает», скорее поддерживает не экви-, а изорекурсивно. Так или иначе, практического вреда от этого немного, и пока ни у кого руки не отсыхали от написания Box<>.

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

Фанатам: прежде чем кидать какахами, посмотрите, что такое АлгТД в википедии и сравните с тем, что есть в Rust.

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

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