Reputation: 5223
For a C routine like
MPI_Comm_rank(MPI_Comm comm, int *rank);
The Rust foreign function interface could be declared like this:
use libc::c_int; // 0.2.79
#[link(name = "mpi")]
extern "C" {
fn MPI_Comm_rank(mpi_comm: c_int, rank: *mut c_int);
}
I call the binding like this, which works, but left me puzzled about syntax:
pub static MPI_COMM_WORLD: libc::c_int = 0x44000000;
fn main() {
let mut rank: c_int = 999999;
/* but why '&mut rank' and not simply '&rank' ? */
unsafe { MPI_Comm_rank(MPI_COMM_WORLD, &mut rank) }
}
I originally tried
unsafe { MPI_Comm_rank(MPI_COMM_WORLD, &rank) }
but this gives a compiler error:
error[E0308]: mismatched types
--> src/main.rs:12:44
|
12 | unsafe { MPI_Comm_rank(MPI_COMM_WORLD, &rank) }
| ^^^^^ types differ in mutability
|
= note: expected raw pointer `*mut i32`
found reference `&i32`
I declared 'rank' as mut, so what gives?
Upvotes: 3
Views: 3350
Reputation: 90742
You’re conflating two completely distinct features.
let mut x;
makes a mutable binding x
, allowing you to modify what x is bound to (x = 42
) and for non-reference types to modify its contents (x.y = 42
). It does not control the mutability of the target of references.
This is different from the type of references you’re dealing with.
&mut T
is a mutable reference and can be coerced to *mut T
.
&T
is an immutable reference can be coerced to *const T
.
As the function you are calling wants *mut T
, you must pass it a *mut T
or a &mut T
; *const T
or &T
will not do.
To be sure, you can only take a mutable reference to mutable data, so let x = 42; &mut x
doesn’t work as it needs let mut x
instead of let x
, but that’s still entirely distinct and is a part of Rust’s rules about mutability.
Upvotes: 8
Reputation: 127751
Your function expects *mut c_int
pointer (a mutable raw pointer), and you need to use &mut
operator to obtain it. However, you can only take &mut
pointer to mut
variables, hence you need to declare rank
variable as mut rank
.
If your function expected *const c_int
pointer, you would be able to use &
, but this is not the case.
Upvotes: 1