[英]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.