Rust中数组原始指针转切片原始指针的合法性与运行疑问
Rust数组原始指针转切片原始指针的疑问
我正在深入理解Rust的原始指针,原本以为下面这段代码会报错(甚至可能存在未定义行为):
fn main() { println!("size of * const u32 ->{}", std::mem::size_of::<* const u32>()); println!("size of * const [u32;13] ->{}", std::mem::size_of::<* const [u32;13]>()); println!("size of * const [u32] ->{}", std::mem::size_of::<* const [u32]>()); let x = 1u32; let arr = [1,2,3,4,5,6,7,8, 9, 10, 11, 12, 13u32]; let px: * const u32 = &x; let parr: * const [u32;13] = &arr; let slice: &[u32] = &arr; let pslice: * const [u32] = slice; unsafe { println!("px -> {:?}", px.as_ref()) }; unsafe { println!("parr -> {:?}", parr.as_ref()) }; unsafe { println!("pslice -> {:?}", pslice.as_ref()) }; // println!("How could this work:"); let pslice2: * const [u32] = parr; // How could this work ? unsafe { println!("pslice2 -> {:?}", pslice2.as_ref()) }; // How could this work ? }
但它甚至在miri下都能正常运行,输出如下:
Standard Error Compiling playground v0.0.1 (/playground) Finished dev [unoptimized + debuginfo] target(s) in 1.16s Running `/playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/cargo-miri runner target/miri/x86_64-unknown-linux-gnu/debug/playground` Standard Output size of * const u32 ->8 size of * const [u32;13] ->8 size of * const [u32] ->16 px -> Some(1) parr -> Some([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]) pslice -> Some([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]) How could this work: pslice2 -> Some([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13])
我能理解切片指针大小为16、数组指针大小为8——毕竟切片类型本身不包含数据长度。但我搞不懂的是,let pslice2: * const [u32] = parr;(parr是*const [u32;13]类型)这行代码为什么能被编译器接受?而且调用as_ref()后还能正常输出数据?
内容的提问来源于stack exchange,提问作者FreD
相关产品推荐
相关产品推荐

