Skip to content

Pointer-to-pointer + casts in FFI leads to hard-to-debug mysterious problems #17417

Closed
@huonw

Description

@huonw

If you have a C API taking a pointer-to-a-pointer, like void**, where the function fills in a pointer value, it's very easy to screw up if there is any pointer casting involved:

extern crate libc;
extern {
    fn c_func(x: *mut *mut libc::c_void);
}

fn main() {
    let x = 0 as *mut u8;
    c_func(&mut (x as *mut libc::c_void));
    println!("new pointer is {}", x);
}

This will always print new pointer is 0x0, no matter what c_func does.

Reason: the x as *mut ... cast is creating a temporary, that's disconnected from the original x and thus the modification happens to the anonymous stack slot that stores the result of the cast. The code should be written something like (&mut x) as *mut _ as *mut *mut libc::c_void.

This is really subtle to debug, so we could have a lint that assists in this case: "did you mean to take a reference to the result of a cast in this FFI call" (could have it apply to non-FFI things too, and presumably it should only apply when there are &mut pointers involved).

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-FFIArea: Foreign function interface (FFI)A-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.C-enhancementCategory: An issue proposing an enhancement or a PR with one.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions