ViZ
ViZ

Reputation: 81

C# unassigned static int results to zero

while experimenting static variables I was amazed to know why the static "int" result to 0 (zero) and non-static result to compile time error.

Consider Case 1

  static int i;
  static void Main()
  {
     Console.Write("Value of i = " + i);
     Console.ReadKey();
  }

the output is

 Value of i = 0

Case 2 with removing static

  static void Main()
  {
     int i;
     Console.Write("Value of i = " + i);
     Console.ReadKey();
  }

And the output for this will result to compile time error

  Error 1   Use of unassigned local variable 'i'

question here is how do both cases differ i.e first one result to 0 and another get compiler error.

Upvotes: 0

Views: 562

Answers (3)

crazy_crank
crazy_crank

Reputation: 699

The existing answers all miss something important here, which is where the variable is declared. Is it a class variable or a local variable

In the first scenario

class Program
{
    static int i;
    static void Main()
    {
       Console.Write("Value of i = " + i);
       Console.ReadKey();
    }
}

The variable i is declared as a class variable. Class variables always get initialized, it doesn't matter if it's static or not. If you don't provide a default value, the variable is assigned default, which in the case of int is 0.

On the other hand, in the second example

class Program
{
    static void Main()
    {
        int i;
        Console.Write("Value of i = " + i);
        Console.ReadKey();
    }
}

Variable i is local variable. Unlike class variables, local variables are never initialized with a default value implicitly, but only when you explicitly initialize them. So the compiler error comes not from the variable being static or not, but from the difference in initialization between local and class variables.

The specification shares some more details on that: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/variables, especially sections 9.2 Variable Types and 9.3 Default Values. The interesting parts are

9.2.2 The initial value of a static variable is the default value (§9.3) of the variable’s type.

9.3.2.2 The initial value of an instance variable of a class is the default value (§9.3) of the variable’s type.

9.2.8 A local variable introduced by a local_variable_declaration is not automatically initialized and thus has no default value. Such a local variable is considered initially unassigned.

9.3: The following categories of variables are automatically initialized to their default values:

  • Static variables.
  • Instance variables of class instances.
  • Array elements.

The underlying reason for this has to do with memory management. When you initialize a class with new() the garbage collector zeros out all bytes on the heap, thus basically defaulting the value of the variable. In case of integers this is 0, for an object reference it would be a null.

Since local variables live on the stack, and the garbage collector doesn't live work on the stack, this guarantee does not exist, so we have explicitly initialize a variable before using it.

Upvotes: 3

Jason Ellingsworth
Jason Ellingsworth

Reputation: 1

Based on my limited understanding, by declaring a variable as static, it becomes existing in memory and is assigned a default value of 0, and does not depend on an instance of the class it is in to exist.

If it is not defined as static, it needs to be initialized within the class(as in, given a value) before it can be used in any logic/math.

Now my confusion comes from being very new, and trying to understand exactly WHY you would choose to do something like this one way, instead of another. Perhaps this is a way to have some values that persist that may be necessary even when the class it is in is not existing, and making everything static would result in ineficient use of memory.

Upvotes: -2

Tsahi Asher
Tsahi Asher

Reputation: 1810

by definition of the C# language, types have "default values", which are assigned to them if you don't assign something else. numbers have a default value of 0, boolean - false, reference types - null, and structs - each member by it's type.

Upvotes: 2

Related Questions