微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

这个“可能未初始化”的编译器错误是误报吗? [rustc 1.51.0] 可能的缓解措施

如何解决这个“可能未初始化”的编译器错误是误报吗? [rustc 1.51.0] 可能的缓解措施

我遇到了可能未初始化的变量错误,但我确信这种情况绝不应该发生。
(rustc --version 是 rustc 1.51.0 (2fd73fabe 2021-03-23)

fn example(discriminant: bool) {
    let value;
    if discriminant {
        value = 0;
    }

    // more code [...]

    if discriminant {
        println!("{}",value);
    }
}

错误信息如下:

    error[E0381]: borrow of possibly-uninitialized variable: `value`
      --> src/raytracing/intersect.rs:8:24
       |
    10 |         println!("{}",value);
       |                        ^^^^^ use of possibly-uninitialized `value`

推理

我确实希望该示例能够编译(尽管如图所示将 if 块分开并不是“好的风格”,恕我直言):

  • 由于 discriminant 是不可变的,我希望第二个 if 块在没有第一个块的情况下永远不会执行。
  • 因此,应始终在 println!() 中借用时定义变量。

可能的缓解措施

可以通过使用临时值初始化 value 来“消除”错误
我强烈反对这种方法,因为

  • 临时值在数学意义上可能是错误的,因为它无法在其他代码路径中计算。
  • 此外,这可能会掩盖在开发过程中未正确定义值的事实,从而限制了编译器发出错误信号的能力。

问题

有人可以澄清这种情况是预期行为还是编译器错误

解决方法

您不是第一个看到这种行为的人,通常我不会认为这是一个错误。在你的情况下,条件非常简单和明显,你和我很容易对这种情况进行推理。但是,通常情况下,条件不需要很明显,例如,即使代码是正确的,第二种情况也可能具有难以推理的其他条件。

此外,您希望编译器进行的那种分析(根据条件确定哪些代码可访问)通常仅在编译器优化时进行。因此,即使编译器支持这种分析,它也可能无法在调试模式下工作。即使在最好的优化编译器和静态分析工具中,它也并非在所有情况下都有效。

如果您对在这种情况下初始化虚拟值有哲学上的反对,您可以使用 Option

fn example(discriminant: bool) {
    let value = if discriminant {
        Some(0)
    } else {
        None
    };

    // more code [...]

    if discriminant {
        println!("{}",value.unwrap());
    }
}

在这种情况下,您的值总是被初始化,在第二部分,您断言它包含一个合适的非 None 值。如果您处于发布模式,编译器可能会确定您的代码是正确的,并对其进行优化以省略 Option(也可能不会)。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。