Question

For a c routine like

MPI_Comm_rank(MPI_Comm comm, int *rank);

the rust foreign function interface could be declared like this:

extern crate libc;
use libc::{c_int};

#[link(name = "mpi")]
extern {
    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:

mismatched types: expected `*mut i32` but found `&i32` (values differ in mutability)

I declared 'rank' as mut, so what gives?

Was it helpful?

Solution

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.

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top