Комментарии 9
Благодарю за отличную работу, хороший цикл статей
А в какой последовательности надо смотреть? Если начинать с этого, то, замечу, мои первые впечатления от Rust бесконечно далеки от показанного. Матан или сопромат, да и просто физ-мат в рамках средней школы на голову сложнее того, что придумано в Rust. Мне ближе такой видеоряд, только титры надо заменить на "Кто писал документацию?!".
Собственно, из-за нее, родимой, и появляются объемистые сторонние обучающие материалы.
Для случаев с нестандартным выравниванием надо использовать 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 запрещает существование экземпляров безопасных типов данных (а ссылки тоже относятся к таковым) в невалидном состоянии.
Выделять типы нулевого размера и пустые типы отдельно от размерных (Sized) некорректно
Замечу, так сделано в документации.
… они так же являются Sized.
Но таки да, это лучше пояснить, поправил.
Работа с кучей в Rust