Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use of unnasigned variable - for loop

Tags:

c#

I have a question regarding assigning value to a variable inside a for loop. I understand that the compiler gives this error message when there is any possibility that a variable may be read when it is not yet assigned, as stated by Microsoft.

Note that this error is generated when the compiler encounters a construct that might result in the use of an unassigned variable, even if your particular code does not.

My code looks like this:

static void Main(string[] args)
{
    int i;

    for (int j = 0; j <= 5; j++)
    {
        i = j;
    }

    Console.WriteLine(i.ToString());

    Console.ReadLine();
}

I presume that even though in this particular scenario i will get assigned, the compiler doesn't check the actual condition inside the for statement, meaning that it would treat

for (int j = 0; j <= -1; j++)

just the same?

like image 415
Kapol Avatar asked Dec 02 '22 20:12

Kapol


2 Answers

Since you are assigning value to variable i inside your for loop, compiler is not smart enough to see whether it will be assigned any value, hence the error.

A simple solution would be to assign some default value to your variable.

int i = 0;

Although from the loop variable values it appears that the control will enter the for loop, but the compiler can't determine that.

The reason for the error is because of the language specification,

5.3 Definite assignment

At a given location in the executable code of a function member, a variable is said to be definitely assigned if the compiler can prove, by static flow analysis, that the variable has been automatically initialized or has been the target of at least one assignment.

Evaluation a condition is not static flow, it would be determined at runtime. Because of that the compiler can't determine whether i would be assigned any value.

like image 131
Habib Avatar answered Dec 05 '22 10:12

Habib


Your current case seems trivial, but what if your loop looks like this:

int i;

for (int j = 0; j <= GetUpperLimit(); j++)
{
    i = j;
}

GetUpperLimit could return 5 like it could return -3 and i will never get assigned. It could be entirely dependent on the state of your application during runtime and the compiler can't know that beforehand, obviously. A simple int i = 0 will solve the issue.

If the condition is a false const or a literal, your for loop will be optimized away. Demo using LINQPad:

int i;

for (int j = 0; j <= -1; j++)
{
    i = j;
}

Resulting IL:

IL_0001:  ldc.i4.0    
IL_0002:  stloc.1     // j
IL_0003:  br.s        IL_000D
IL_0005:  nop         
IL_0006:  ldloc.1     // j
IL_0007:  stloc.0     // i
IL_0008:  nop         
IL_0009:  ldloc.1     // j
IL_000A:  ldc.i4.1    
IL_000B:  add         
IL_000C:  stloc.1     // j
IL_000D:  ldloc.1     // j
IL_000E:  ldc.i4.m1   
IL_000F:  cgt         
IL_0011:  ldc.i4.0    
IL_0012:  ceq         
IL_0014:  stloc.2     // CS$4$0000
IL_0015:  ldloc.2     // CS$4$0000
IL_0016:  brtrue.s    IL_0005

Now with a false literal instead of an expression:

int i;

for (int j = 0; false; j++)
{
    i = j;
}

Resulting IL:

IL_0001:  ldc.i4.0    
IL_0002:  stloc.1     // j
IL_0003:  br.s        IL_0005
IL_0005:  ldc.i4.0    
IL_0006:  stloc.2     // CS$4$0000

Similarly, if(false) { ... } is optimized, but not bool b = false; if(b) { ... }. This is all a result of static analysis.

like image 22
dee-see Avatar answered Dec 05 '22 08:12

dee-see