Отказ от ответственности: пока нет формальной модели памяти. 1
Прежде всего, я хотел бы обратиться к:
Проблема, которую я вижу здесь, состоит в том, что x
, являясь ссылкой &mut
, может считаться уникальным для компилятора.
Да ... и нет.x
можно считать уникальным , если не заимствовано , важное отличие:
fn doit(x: &mut T) {
let y = &mut *x;
// x is re-borrowed at this point.
}
Поэтому в настоящее время я буду работать с предположением, что вывод указателя из x
временно "заимствует" x
в некотором смысле.
Это все, конечно, бесполезно, если нет формальной модели, и одна из причин того, почему компилятор rustc не слишком агрессивен с псевдонимамиоптимизаций пока нет: пока формальная модель не определена и код не проверен на соответствие, оптимизации должны быть консервативными.
1 Проект RustBelt полностью посвящен созданию формально проверенной моделиМодель памяти для Rust.Последние новости от Ральфа Юнга были о Stacked Borrows модели .
От Ralf (комментарии): ключевой момент в приведенном выше примере заключается в том, чтоперейдите с x
на x_ptr
и обратно на x
снова.Таким образом, x_ptr
в определенном смысле является заимствованным объемом.Если использование перейдет на x
, x_ptr
, обратно к x
и обратно к x_ptr
, то последним будет неопределенное поведение:
fn main() {
let x = &mut [1, 2, 4];
let x_ptr = x.as_mut_ptr(); // x_ptr borrows the right to mutate
unsafe {
for i in 0..x.len() {
*x_ptr.offset(i as isize) += 2; // Fine use of raw pointer.
}
}
assert_eq!(x, &[3, 4, 6]); // x is back in charge, x_ptr invalidated.
unsafe { *x_ptr += 1; } // BÄM! Used no-longer-valid raw pointer.
}