未分配的局部变量和短路评估

hou*_*uen 6 c#

我有两种方法,它们都正确编译:

public int A()
{
    int i;
    if(!int.TryParse("0", out i))
    {
        return -1;
    }
    // do sth
    return i;
}

public int B()
{
    int i;
    if(true)
    {
        return -1;
    }
    return i;
}
Run Code Online (Sandbox Code Playgroud)

在第二种情况(方法B)中,编译器足够聪明,可以检测到该变量i从未被使用过,所以它不会抱怨不分配它.

但是,我有另一个例子(两者的组合)似乎等同于方法B:

public int C()
{
    int i;
    if (true || !int.TryParse("0", out i))
    {
        return -1;
    }
    return i;
}
Run Code Online (Sandbox Code Playgroud)

VisualStudio 2012(.NET Framework 4.6.01055)下在Windows上进行编译时,会抛出错误:Use of unassigned local variable 'i'.解决方案是:

  • i用任何值初始化,或
  • 使用|运算符代替||.

为什么会这样?看起来编译器具有检测无法访问代码的所有必要数据.

附注:示例在单声道4.6.2下的Linux上进行C编译,并提供有关无法访问的代码的警告.

InB*_*een 1

这不能被视为一个错误,但它是一个可以改进的功能。当您说编译器有足够的信息来知道i从未使用未分配的内容时,您是正确的,因此它应该忽略编译器错误。

它可以改进,因为事实上它已经改进了;在 VS 2015 中,编译器的行为是预期的:没有编译时错误。我不能对以前版本的编译器说同样的话,因为我现在无法测试它们。

有趣的是,VS 2015 或 VS 2017 RC 都没有报告无法访问的代码警告,这return i似乎有点奇怪。if (true)将给出此警告并if (true || ....)正确地计算出i未使用的内容,但由于我不明白的原因,该警告已被省略。

要更多地了解行为改变的原因,请查看此答案。我知道这个问题很响……几年前我自己也问过类似的问题;)。