views:

289

answers:

4

Check this code..

    string str;

    if (str.Contains("something.."))
    {
    }

Compiler throws this error for this code

Use of unassigned local variable 'str'

Why does a reference type is not initialized to null ?

Just want to know out of curiosity.

I'd also want to know what happens for code below. how does this assignment work ?

    string str = null;
+10  A: 

Only fields (variables declared at class level) are initialized automatically:

  • Value types are initialized to their default value.
  • Reference types are initialized to null reference.

What you are declaring is a "local variable" inside a method. Local variables are not automatically initialized regardless of being a value type or reference type.

I'd also want to know what happens for code below. how does this assignment work ?

This assignment initializes the local variable with null value with an ldnull instruction followed by a stloc instruction (in case it's not optimized out, of course) and more importantly, satisfies the compiler's data flow analysis rules for definite assignment. C# specification defines a concept called definite assignment that ensures a variable is assigned before first use.

Mehrdad Afshari
Are you talking about fields that are reference-types and still initialized as null ? Then why such a difference ?
this. __curious_geek
Difference between what? Being local or not?
Mehrdad Afshari
@Mehrdad: I think he wants to know why local variables are not automatically initialized to their default value as opposed to fields. The reason is because this is already an optimization. The compiler can safely say whether a local variable is assigned a value or not. If it isn't the compiler will throw an error at compile time. This optimization wouldn't be possible for fields.
Yannick M.
From the language perspective, it's helping you possibly iron out bugs that might cause as a result of you forgetting the initialization. From the runtime's perspective, when it allocates memory for an object on the heap, it zeros out the block before handing it to you eliminating the need for manual initialization.
Mehrdad Afshari
A: 

Keep in mind as well that calling Contains on a null string will throw a NullReferenceException.

Adam Gritt
this won't compile at all.
this. __curious_geek
I guess I miss understood. I thought you were also asking what would happen if you had the code setting the str variable to null. In that case the exception would occur.
Adam Gritt
+3  A: 

It does get initialized to null. The compiler just did you a favor by not having to debug the inevitable NullReferenceException you'll get.

Hans Passant
Mehrdad is right, local variables don't actually get initialized, as it would be pointless since you cannot use a local variable until it is assigned a value, the compiler won't let you :-)
Yannick M.
Hmya, chicked-and-egg problem. It is permitted in VB.NET, it doesn't generate any IL to initialize the local variable. Initialization is done by the JIT compiler.
Hans Passant
+4  A: 

The C# langauge requires that all variables be definitely assigned to before they are read from. Local variables are considered to be initially unassigned, whereas fields, array elements, and so on, are considered to be initially assigned to their default value. (Which, for a reference type, is null.)

There is no technical reason why we couldn't treat local variables as initially assigned to their default values and throw away all the definite assignment checking. It's there because using an unassigned local as its default value is (1) a bad coding practice, and (2) a highly probable source of irritating bugs. By requiring you to explicitly assign local variables before they are used, we prevent the user from using a bad practice, and eliminate a whole class of bugs that you then never have to debug.

Also, consider the following:

while(whatever)
{
    int i;
    print(i);
    i = i + 1;
}

Do you expect i to hold its value across executions of the loop, or for it to be initialized fresh to zero every time? By forcing you to explicitly initialize it, the question becomes meaningless and this is a difference which makes no difference.

(Also, in the case above there is a small potential performance optimization, in that the compiler could re-use the variable without having to generate code to clear its contents because the compiler knows that you will clear the contents.)

I don't know how to answer your second question because I don't know what you mean by "work". Can you tell me how assigning "int x = 123;" works? Once I know what you mean by "works" then I can describe how assigning a null to a variable of reference type works.

Eric Lippert