簡體   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