提问人:Timothée Delabrouille 提问时间:10/27/2023 最后编辑:Colonel Thirty TwoTimothée Delabrouille 更新时间:10/29/2023 访问量:42
包装器类型之间的不安全类型转换
unsafe type casting between wrappers types
问:
struct Wrapper1(u32);
impl Wrapper1 {
fn inner(&self) -> &u32 {
&self.0
}
}
struct Wrapper2(u32);
struct Wrapper3(Wrapper1);
trait GetInner {
fn inner(&self) -> &Wrapper2;
}
impl GetInner for Wrapper3 {
fn inner(&self) -> &Wrapper2 {
let raw_pointer = self.0.inner() as *const u32 as *const Wrapper2;
unsafe { &*raw_pointer }
}
}
我有这段代码片段,展示了我的问题的简化。
我必须依靠,因为我不能只这样做:unsafe
impl GetInner for Wrapper3 {
fn inner(&self) -> &Wrapper2
&Wrapper2(*self.0.inner())
}
}
声音好吗?我的团队中有人对一致性提出了担忧。
其他人提到我们必须在包装器类型上使用,以使其更安全。#[repr(transparent)]
答:
0赞
Chayim Friedman
10/29/2023
#1
您需要是 或 .不保证结构的布局。Wrapper2
#[repr(transparent)]
#[repr(C)]
#[repr(Rust)
但是,如果你这样做了,你就不再需要不安全了 - 你可以使用 bytemuck
:
struct Wrapper1(u32);
impl Wrapper1 {
fn inner(&self) -> &u32 {
&self.0
}
}
#[derive(bytemuck::TransparentWrapper)]
#[repr(transparent)]
struct Wrapper2(u32);
struct Wrapper3(Wrapper1);
trait GetInner {
fn inner(&self) -> &Wrapper2;
}
impl GetInner for Wrapper3 {
fn inner(&self) -> &Wrapper2 {
bytemuck::TransparentWrapper::wrap_ref(self.0.inner())
}
}
评论
#[repr(transparent)]
u32
#[repr(transparent)]
For types with niches it may do "weird" things even for simple cases.
您能否对此进行扩展并分享有关此现象的一些链接?总结一下你的观点: - 如果我使用它会是合理的 - 如果我不这样做,可能会导致未定义的行为(尤其是对于更复杂的内部类型)#[repr(transparent)]