In my Rust program, I'm getting back values of the form *mut Foo
from a function written in C.
let x: *mut Foo = my_ffi_function();
What does this "*mut" notation even mean?
As far as I can tell, x
is just a pointer to a mutable Foo struct, the same as &mut Foo
.
This code compiles just fine:
let mut s: String = String::new();
let x: &mut String = &mut s;
let y: *mut String = x;
What's difference between the two forms?
&mut Foo
is a reference while *mut Foo
is a pointer.
At runtime they are essentially the same thing; just an address to some other location in memory.
The difference is that references are checked by the compiler and must always be valid (point to an allocated, non-null, aligned, initialized value). To aid in that, a reference type also has an associated lifetime (annotated &'lifetime mut Foo
) that is used by the compiler during the borrow checking step. This is the primary mechanism by which Rust ensures memory safety.
By contrast, the compiler does not check that pointers are valid. Pointers can be null, they can point to mis-aligned data, or to no value at all. Because of this, very little can be done with pointers in safe Rust and therefore access through the pointer must be done within an unsafe
block. This is generally to be avoided since unsafe
code is tricky to get right, but may be required in complex or performance sensitive scenarios (or frequently in FFI).
Your code block just demonstrates that references can be coerced into pointers.