Rust的临时指针是否正常?

Tim*_*mmm 11 rust

我有这样的功能:

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

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

Layout可转换.into()的可复制类型在哪里RawLayout

我想确保我理解发生的事情,因为它不安全.据我所知,layout.into()创建一个临时的RawLayout,然后&对它进行引用,as *const _并将其转换为原始指针(*const RawLayout).然后foo()调用该函数并返回,最后RawLayout删除临时函数.

那是对的吗?还是有一些棘手的原因我不应该这样做?

aoc*_*via 4

你是对的。在这种情况下,foo首先被调用,然后RawLayout被删除。The Rust Reference对此进行了解释(点击链接查看实践中如何实现的具体示例):

临时值的生命周期通常是最内层的封闭语句

不过,我宁愿听从 Shepmaster 的建议。显式引入局部变量将帮助代码读者专注于更重要的事情,例如确保不安全代码是正确的(而不是必须弄清楚临时变量的确切语义)。

如何检查这个

您可以使用下面的代码来检查此行为:

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);    
}
Run Code Online (Sandbox Code Playgroud)

输出是:

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);    
}
Run Code Online (Sandbox Code Playgroud)