Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are raw pointers to temporaries ok in Rust?

Tags:

rust

I have a function like this:

extern {
    fn foo(layout: *const RawLayout) -> libc::uint8_t;
}

fn bar(layout: Layout) -> bool {
    unsafe {
        foo(&layout.into() as *const _) != 0
    }
}

Where Layout is a copyable type that can be converted .into() a RawLayout.

I want to make sure I understand what is happening as it is unsafe. As I understand it, layout.into() creates a temporary RawLayout, then & takes a reference to it, and as *const _ converts it to a raw pointer (*const RawLayout). Then the foo() function is called and returns, and finally the temporary RawLayout is dropped.

Is that correct? Or is there some tricky reason why I shouldn't do this?

like image 968
Timmmm Avatar asked Jan 23 '17 21:01

Timmmm


1 Answers

You are right. In this case, foo is called first and RawLayout is dropped afterwards. This is explained in The Rust Reference (follow the link to see concrete examples of how this works out in practice):

The lifetime of temporary values is typically the innermost enclosing statement

However, I would rather follow Shepmaster's advice. Explicitly introducing a local variable would help the reader of the code concentrate in more important things, like ensuring that the unsafe code is correct (instead of having to figure out the exact semantics of temporary variables).

How to check this

You can use the code below to check this behavior:

struct Layout;
struct RawLayout;

impl Into<RawLayout> for Layout {
    fn into(self) -> RawLayout {
        RawLayout
    }
}

impl Drop for RawLayout {
    fn drop(&mut self) {
        println!("Dropping RawLayout");
    }
}

unsafe fn foo(layout: *const RawLayout) -> u8 {
    println!("foo called");
    1
}

fn bar(layout: Layout) -> bool {
    unsafe {
        foo(&layout.into() as *const _) != 0
    }
}

fn main() {
    bar(Layout);    
}

The output is:

foo called
Dropping RawLayout
like image 66
aochagavia Avatar answered Oct 20 '22 04:10

aochagavia