gpt4 book ai didi

rust - 将结构转换为数组是否合法?

转载 作者:行者123 更新时间:2023-12-03 11:25:59 24 4
gpt4 key购买 nike

考虑以下几点:

// Just a sequence of adjacent fields of same the type
#[repr(C)]
#[derive(Debug)]
struct S<T> {
a : T,
b : T,
c : T,
d : T,
}

impl<T : Sized> S<T> {
fn new(a : T, b : T, c : T, d : T) -> Self {
Self {
a,
b,
c,
d,
}
}
// reinterpret it as an array
fn as_slice(&self) -> &[T] {
unsafe { std::slice::from_raw_parts(self as *const Self as *const T, 4) }
}
}

fn main() {
let s = S::new(1, 2, 3, 4);

let a = s.as_slice();

println!("s :: {:?}\n\
a :: {:?}", s, a);
}
  • 此代码是否可移植?
  • 假设具有相同类型字段的 repr(C) 结构可以像数组一样重新解释总是安全的吗?为什么?

最佳答案

是的,它是安全和便携的,除了非常大的T (在下面修复)。 std::slice::from_raw_parts 文档的安全部分中没有列出任何要点这里有一个问题:

  • 数据指针对mem::size_of::<T>() * 4有效, 这是 S<T> 的大小, 并正确对齐。

    • 所有项都在同一个分配对象中,因为它们在同一个结构中。
    • 指针不为空,因为它是从保险箱 &self 中转换而来的参数,并且正确对齐,因为 S<T>具有(至少)T 的对齐方式.
  • data参数肯定指向4个连续初始化T s,因为S标记为 #[repr(C)]哪个is defined such that在您的结构中,不会引入任何填充。 (repr(Rust) 不作此类保证)。

  • 引用的内存在引用的生命周期内不会发生变化,这是由借用检查器保证的。

  • 切片的总大小不得大于 isize::MAX .代码不会对此进行检查,因此从技术上讲这是一个安全漏洞。可以肯定的是,在 as_slice 上打勾, 在 unsafe 之前:

    assert!(std::mem::size_of::<S<T>>() <= isize::MAX as _);

    检查通常会被优化掉。

关于rust - 将结构转换为数组是否合法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62240126/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com