В чем разница между & mut unsafe {} и unsafe {& mut}? - PullRequest
8 голосов
/ 05 мая 2020

Я хочу преобразовать *mut указатель в &mut ссылку.

// Both setting a value to ptr and getting a value from ptr succeeds.
let ptr: &mut usize = unsafe { &mut *(VIRTUAL_ADDRESS_TO_ACCESS_FREE_PAGE as *mut usize) };

Это работает. Однако, если &mut находится за пределами блока unsafe, код не будет работать частично. *ptr = foo не сохранит foo в памяти ptr точек, но let foo = *ptr присвоит значение *ptr foo.

// Setting a value to ptr fails, but getting a value from ptr succeeds.
let ptr: &mut usize = &mut unsafe { *(VIRTUAL_ADDRESS_TO_ACCESS_FREE_PAGE as *mut usize) };

В чем разница между unsafe { &mut } и &mut unsafe{ }?

1 Ответ

10 голосов
/ 05 мая 2020

Это не имеет ничего общего с unsafe как таковым, скорее с границами блоков .

&*ptr - это «перезайм», он просто переинтерпретирует указатель на новую форму. Таким образом, вы получаете разные типы указателей (один необработанный и одна ссылка) на один и тот же объект.

&{*ptr} совершенно разные, потому что {*ptr} будет принудительно скопировать [ 0] (спасибо @ harmi c за источник):

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

Затем он заимствует эту копию. Это означает, что вы получаете два указателя на совершенно разные объекты .

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

См. эту демонстрацию (без использования указателей mut, потому что есть нет необходимости демонстрировать проблему)


[0] в более общем плане ход, но здесь вы указываете на usize, который является копией

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...