Как стать автором
Обновить

Комментарии 9

Спасибо за разъяснение. Рекомендую ютуб-канал с уроками по rust: D-web. С достаточно понятной и интересной интерпретацией инфы, и связной логикой уроков!

А в какой последовательности надо смотреть? Если начинать с этого, то, замечу, мои первые впечатления от Rust бесконечно далеки от показанного. Матан или сопромат, да и просто физ-мат в рамках средней школы на голову сложнее того, что придумано в Rust. Мне ближе такой видеоряд, только титры надо заменить на "Кто писал документацию?!".


Собственно, из-за нее, родимой, и появляются объемистые сторонние обучающие материалы.

Начинать лучше сначала плей-листа с уроками - с установки vc code и базовых понятий типа переменные, функции, структуры... Эти видео, на которые Вы ссылаетесь понятны, если уже просмотрел все предыдущие)

Для случаев с нестандартным выравниванием надо использовать ptr::addr_of!() / ptr::addr_of_mut!()

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


Выделять типы нулевого размера и пустые типы отдельно от размерных (Sized) некорректно, они так же являются Sized.


Важно: Деструктор для p при этом НЕ вызывается, т.е. Rust как бы "забывает" про эту переменную

Это не является особым случаем, а лишь проявлением того факта, что <*mut T>::write, как и любая функция, принимает владение переданным аргументом. То, что происходит с переданным значением внутри функции, извне уже не контролируется. Там вполне могут вызвать std::mem::forget, внешне эффект будет тот же, то есть отсутствие вызова деструктора.

Дело не в выравнивании

Документация прямо указывает, что "// &packed.f2 would create an unaligned reference, and thus be Undefined Behavior!".


Да и не скомпилируется вот такой пример без allow(unaligned_references):


#[repr(packed)]
struct Packed {
    f1: u8,
    f2: u16,
}

#[allow(unaligned_references)]
fn main(){

    let packed = Packed { f1: 1, f2: 2 };

    // `&packed.f2` would create an unaligned reference, and thus be Undefined Behavior!
    let pf2 = &packed.f2 as *const _ as *const u16;

    unsafe {dbg!(*pf2)};
    dbg!(packed.f1);

}

а правила языка требуют, чтобы ссылки указывали только на инициализированные данные, нарушение это правила — это неопределённое поведение.

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

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

https://doc.rust-lang.org/stable/std/ptr/macro.addr_of.html


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

Понятно. Замечу, что в стабильных рамках языка Rust (если к языку не относить макрос std::ptr::addr_of!()) нельзя получить и raw pointer на невыровненные/неинициализированные/ данные.

Выделять типы нулевого размера и пустые типы отдельно от размерных (Sized) некорректно

Замечу, так сделано в документации.


… они так же являются Sized.

Но таки да, это лучше пояснить, поправил.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории