gpt4 book ai didi

casting - 转换任意类型以使用的安全性

转载 作者:行者123 更新时间:2023-11-29 07:51:36 24 4
gpt4 key购买 nike

我写了一些代码。它有效……但它安全吗?

use std::mem;
use std::ptr;
use std::marker::PhantomData;

struct Atomic<T: Copy>(AtomicUsize, PhantomData<T>);

impl<T: Copy> Atomic<T> {
unsafe fn encode(src: T) -> usize {
assert!(mem::size_of::<T>() <= mem::size_of::<usize>());

let mut dst = 0;
ptr::write(&mut dst as *mut usize as *mut T, src);
dst
}

unsafe fn decode(src: usize) -> T {
assert!(mem::size_of::<T>() <= mem::size_of::<usize>());
ptr::read(&src as *const usize as *const T)
}

fn new(val: T) -> Atomic<T> {
unsafe {
Atomic(AtomicUsize::new(Self::encode(val)), PhantomData)
}
}

fn load(&self, order: Ordering) -> T {
unsafe { Self::decode(self.0.load(order)) }
}

fn store(&self, val: T, order: Ordering) {
unsafe { self.0.store(Self::encode(val), order) }
}
}

impl<T: Copy + Default> Default for Atomic<T> {
fn default() -> Atomic<T> {
Self::new(T::default())
}
}

如你所见,我写了一个任意的 Copy足够小的值变成 usize ,并以 Atomic 的形式运送它.然后我将其作为新值读出。

本质上我使用 usize作为大小为 size_of::<usize>() 的内存块.

如果这是安全的,下一步就是考虑更高级的操作。

unsafe trait PackedInt {}
unsafe impl PackedInt for u8 {}
unsafe impl PackedInt for i8 {}
unsafe impl PackedInt for u32 {}
unsafe impl PackedInt for i32 {}
unsafe impl PackedInt for u64 {}
unsafe impl PackedInt for i64 {}

impl<T: Copy + PackedInt> Atomic<T> {
fn compare_and_swap(&self, current: T, new: T, order: Ordering) -> T {
unsafe {
Self::decode(self.0.compare_and_swap(
Self::encode(current),
Self::encode(new),
order
))
}
}

fn fetch_add(&self, val: T, order: Ordering) -> T {
unsafe {
Self::decode(self.0.fetch_add(Self::encode(val), order))
}
}

fn fetch_sub(&self, val: T, order: Ordering) -> T {
unsafe {
Self::decode(self.0.fetch_sub(Self::encode(val), order))
}
}
}

当然,这些在溢出时并不总是特别敏感(因为两个“相等”的值可能由于 T 之外的位而比较不相等),但它们看起来仍然定义明确......我认为。

那么,这安全吗?为什么?

最佳答案

这几乎是安全的……但不完全是。您可能只考虑使用 Atomic 的人有整数和 float ,但引用也是 Copy .用户在 Atomic<&&u32> 上使用宽松的加载和存储很容易导致崩溃.

在旁注中,您的 fetch_addfetch_sub无法在大端系统上正常工作。

关于casting - 转换任意类型以使用的安全性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32822683/

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