这个“可能未初始化”的编译器错误是误报吗?[生锈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所示-blocks 分开并不是“好风格”恕我直言):

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

可能的缓解措施

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

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

问题

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

bk2204

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

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

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

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

    // more code [...]

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

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

现代C ++编译器会自动将局部变量初始化为0吗?

***-[__ NSArrayM objectAtIndex:]:当我使用UIsearchbar和UItableview时,索引51超出范围[0 .. 50]错误

14.04-自从3.16-0-51通用内核更新以来无法打印-如何报告错误

未初始化的成员未被编译器捕获。这是一个错误吗?

Python类型错误(dtype('<U51')

C51 C编译器内联汇编到SDCC内联汇编

“当前消息级别:0x00000033(51)”是什么意思?

初始化多维数组:{0}与{{{0}}}

这个 50/51 问题出了什么问题?

除以0是编译器错误或运行时错误

未初始化变量的错误编译器错误用法

错误的函数初始化和警告:函数hello_world / 0未使用

我不明白的编译器警告-可能未初始化的QStringList

未初始化的指针与NULL和0

Lambda函数导致参数0的编译器错误,1或多个的异常

catch块中的throw语句如何防止未初始化变量的编译器错误?

编译器错误“变量x可能尚未初始化”的含义是什么?

编译器会优化集合初始化吗?

ant和Java 8-“主版本52比51(该编译器支持的最高主版本)新”

VoiceCommandDefinition初始化中的错误0x80045561

错误:初始化:ttyS0(/ dev / ttyS0)主进程(1612)以状态1终止

大括号初始化数字类型。它们是0初始化的吗?

0/0 (NAN) 和 1/0 (INF) 的字节表示在任何 C 编译器和机器上都相同吗?

为什么编译器左移0?

未初始化为0的对象数组

用{0}或{'\ 0'}初始化结构之间有什么区别吗?

为什么编译器报告“可能在此函数中未初始化使用”?

如何在 Rust 代码中使用延迟初始化并通过编译器“可能未初始化的变量”规则?

初始化后整数变为0