繁体   English   中英

repr(C)和repr(rust)有什么区别?

[英]What is the difference between repr(C) and repr(rust)?

我正在编写一个Vulkan渲染器,我刚刚意识到我应该只接受repr(C)类型,但据我所知,在编译时无法实际检查它。

struct Vertex {
    x: f32,
    y: f32,
    b: Box<f32>
}

#[repr(C)]
struct Vertex2 {
    x: f32,
    y: f32,
    b: Box<f32>
}

fn to_bytes<T>(t: &T) -> &[u8]{
    let p: *const T = t;
    let p = p as *const u8;
    unsafe{
        std::slice::from_raw_parts(p, std::mem::size_of::<T>())
    }
}

fn main() {
    let v = Vertex{x: 42.0, y: 0.0, b: Box::new(42.0)};
    let v2 = Vertex2{x: 42.0, y: 0.0, b: Box::new(42.0)};
    println!("{:?}", to_bytes(&v));
    println!("{:?}", to_bytes(&v2));
}

操场

经过几次尝试,我终于可以看到repr(c)repr(rust)之间的区别,但只有当我使用Box

repr(C)repr(rust)什么区别? 我可以假设如果一个类型只包含其他POD类型,那么布局将与C中的相同吗?

例:

let slice = base.device
    .map_memory::<Vertex>(vertex_input_buffer_memory,
                          0,
                          vertex_input_buffer_info.size,
                          vk::MemoryMapFlags::empty())
    .unwrap();
slice.copy_from_slice(&vertices);

资源

我正在填写一个缓冲区,我交给Vulkan,所以我认为这里的布局可能很重要。

您在程序输出中看到的差异不是由于内存布局。 Box<T>堆分配并存储指向堆内容的指针,因此您要打印的是指针。 由于Box<T>不执行任何实习/对象池,因此这两个地址当然是不同的。 可能有点令人困惑的是地址彼此如此接近。 这只与jmalloc有关,这是分配器Rust使用的,它有用于小分配的密集池。

我可以假设如果一个类型只包含其他POD类型,那么布局将与C中的相同吗?

不,你几乎不能假设Rust的类型内存布局。 故意不指定这允许优化,例如字段重新排序。 即使现在repr(Rust)repr(C)非常接近,你也不能认为它会永远像那样。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM