gpt4 book ai didi

rust - mem::forget(mem::uninitialized()) 是否定义了行为?

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

mutagen , 我正在注入(inject)各种代码中的突变。我想改变的一件事是模式 if let Ok(x) = y { .. } .然而,这构成了相当大的挑战,因为我不知道 y 的类型– 用户可以构建自己的枚举一元 Ok变种。对于我们的情况,我仍然可以机会主义地改变它实际上有一个Result其错误类型实现 Default使用特征看起来像以下简化的:

#![feature(specialization)]

pub trait Errorer {
fn err(self, mutate: bool) -> Self;
}

impl<X> Errorer for X {
default fn err(self, _mutate: bool) -> Self {
self
}
}

impl<T, E> Errorer for Result<T, E>
where
E: Default,
{
fn err(self, mutate: bool) -> Self {
if mutate {
Err(Default::default())
} else {
self
}
}
}

唉,实现Default的错误并不多, 所以这是不太有用。甚至是 Result<T, Box<Error>> 的实现会给我们更物有所值(并且完全有可能)。然而,鉴于我不太关心实际检查错误的代码,我想知道我是否可以通过将上述代码的突变扩展为

match Errorer::err(y, mutation) {
Ok(x) => { .. }
Err(x) => { mem::forget(x); }
}

并且有err返回 Err(mem::uninitialized())变异时——这也是行为安全?注意:我回来了 Err(mem::uninitialized())从一个方法,只到 mem::forget稍后。我看不出这会引起 panic ,所以我们应该假设该值确实会被遗忘。

这是定义的行为还是我应该期待鼻恶魔?

最佳答案

不,这不是定义的行为,至少不是对所有类型。 (我不知道你的代码将如何作为突变的一部分被调用,所以我不知道你是否可以控制这里的类型,但是通用 impl 肯定会让它看起来像你没有。)这已经证明通过以下代码:

#![feature(never_type)]
use std::mem;

fn main() {
unsafe { mem::forget(mem::uninitialized::<!>()) }
}

如果你run this on the playground ,您将看到该程序因 SIGILL 而终止。 ASM 输出显示 LLVM 刚刚优化了整个程序以立即发送 SIGILL,因为它使用无人居住类型的值的方式 ! :

playground::main:
ud2

一般来说,要正确使用mem::uninitialized几乎是不可能的。在通用代码中,参见例如this issue of rc::Weak .因此,该功能正在成为 deprecated and replaced。 .但这对你没有帮助;你想做的对Result<T, !>来说是完全非法的.

关于rust - mem::forget(mem::uninitialized()) 是否定义了行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50184028/

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