Unallocated Local Variable and Short Circuit Estimation

I have two methods, both compile 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 ), the compiler is smart enough to detect that the variable i never used, so it does not complain that it does not assign 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 gives an error: Use of unassigned local variable 'i' . Decision:

  • initialize i any value or
  • use | instead of || .

Why is this so? It seems that the compiler has all the necessary data to detect unreachable code.

Side note . Example C compiles on Linux in mono version 4.6.2 with warnings about unreachable code, as expected.

+6
source share
2 answers

This may not be considered a mistake, but its improved function. You are right when you say that the compiler has enough information to know that unassigned i never used, and therefore it should omit the compiler error.

It has improved because, in fact, it has improved; in VS 2015, compiler behavior is expected: there is no compile-time error. I cannot say the same for previous versions of the compiler, because I cannot check them at the moment.

Oddly enough, neither VS 2015 nor VS 2017 RC report an invalid code warning in return i , which seems a bit strange. if (true) will give this warning, and if (true || ....) correctly display that i not used, but the warning was omitted for reasons that I do not understand.

To learn more about why behavior was changed, check out this. I knew that this question rings the bell ... I asked a similar person a couple of years ago myself;).

+1
source

When compiling on Windows under Visual Studio 2012 (.NET Framework 4.6.01055), it gives an error: using an unassigned local variable "i"

As it should be. Variable not assigned. You cannot reference it in code. Sometimes, although, depending on the compiler, it may know in advance that the string is never executed and completely deletes it before checking the use of the variable. Other versions may switch steps, which may lead to different results. Personally, I would say that you should not rely on this: safe code.

Just for your information. Roslyn (the latest .NET compiler) does not give compilation errors. It seems like the check just cancels all the conditions || .

 if (true || !int.TryParse("0", out i)) // // does not give an error, first return always used, other discarded if (true && !int.TryParse("0", out i)) // does not give an error, i is known to always be assigned if (false && !int.TryParse("0", out i)) // gives an error, if never results in true, and parse is known not to be called 
0
source

Source: https://habr.com/ru/post/1014221/


All Articles