Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unassigned local variable and short-circuit evaluation

Tags:

c#

I have two methods, both of them compiles correctly:

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;
}

In the second case (method B) compiler is smart enough to detect that variable i is never used so it doesn't complain about not assigning it.

However, I have another example (a combination of both) that seems to be equivalent to method B:

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

When compiling on Windows under VisualStudio 2012 (.NET Framework 4.6.01055) it throws an error: Use of unassigned local variable 'i'. The solution is to:

  • initialize i with any value, or
  • use | operator instead of ||.

Why is that so? It looks like a compiler has all the necessary data to detect unreachable code.

Side note: Example C compiles on Linux under mono 4.6.2 with warnings about unreachable code as expected.

like image 416
houen Avatar asked Jan 19 '17 13:01

houen


1 Answers

This can't be considered a bug but its an improvable feature. You are correct when you say that the compiler has enough information to know that the unassigned i is never used and therefore it should omit the compiler error.

Its improvable because, as a matter of fact, it has been improved; in VS 2015 the behavior of the compiler is the expected one : no compile time error. I can't say the same thing for previous versions of the compiler because I can't test them at the moment.

Funnily enough, neither VS 2015 or VS 2017 RC report an unreachable code warning at return i which seems a bit odd. if (true) will give this warning and if (true || ....) figures out correctly that i is not used, but the warning has been omitted for reasons I dont understand.

For more insight on why the behavior was changed, check out this answer. I knew this question rung a bell...I asked a similar one a couple years ago myself ;).

like image 167
InBetween Avatar answered Oct 24 '22 15:10

InBetween