zzfima
zzfima

Reputation: 1565

Use of unassigned local variable: value type vs custom struct

A primitive C# value type, for example int is a struct. So, why is int not initialized? There supposed to be default constructor, I think. On the other hand, a custom struct is ok.

In the following code

struct STRCT { }
class Program
{
    static void Main(string[] args)
    {
        STRCT strct;
        strct.Equals(8);
        strct.GetHashCode();
        strct.GetType();
        strct.ToString();

        int i;
        i.Equals(8);
        i.GetHashCode();
        i.GetType();
        i.ToString();
    }
}

while first 5 lines of code are ok from the C# compiler view, next 5 lines of code generates compile error:

use of unassigned local variable

Please, explain why? From my point of view both types are structs and shall have the same behavior.

Upvotes: 4

Views: 1223

Answers (4)

kgzdev
kgzdev

Reputation: 2885

Structs are value types

Unlike reference types, a value type cannot contain the null value. However, the nullable types feature does allow for value types to be assigned to null. Each value type has an implicit default constructor that initializes the default value of that type. For information about default values of value types

See - https://msdn.microsoft.com/en-us/library/s1ax56ch.aspx

Upvotes: 0

Matthew Watson
Matthew Watson

Reputation: 109597

This is because, unlike the int, your STRCT doesn't contain any fields and therefore doesn't contain anything that could be "unassigned".

Try changing it to:

struct STRCT
{
    public int X;
}

Then you'll get the same compile error:

Error CS0165 Use of unassigned local variable 'strct' ConsoleApplication1 D:\Test\CS6\ConsoleApplication1\Program.cs 15

The C# language specification has explicit rules for "Definite Assignment" in section 5.3:

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 a particular static flow analysis (§5.3.3), that the variable has been automatically initialized or has been the target of at least one assignment

And then:

A struct-type variable is considered definitely assigned if each of its instance variables is considered definitely assigned.

So from that last rule, if a struct has no instance variables (i.e. fields) then it is considered to be "definitely assigned", and therefore no compile error will be omitted.

Upvotes: 5

Damien_The_Unbeliever
Damien_The_Unbeliever

Reputation: 239714

It's a pathological extreme of the rules of Definite Assignment. Specifically:

A struct-type variable is considered definitely assigned if each of its instance variables is considered definitely assigned.

In this case (STRCT strct), the set of instance variables is empty, and so it is true that they've all been definitely assigned.

Upvotes: 8

nikovn
nikovn

Reputation: 2000

It's class Members that are automatically initialized - so if your int was a field or a property in a class, you'd fine.

However, local variables to a method are not initialized and expect you to give them a value.

Your struct variable works ok for the time being, since it contains no members of its own. Once you add

struct STRCT
{
    private int a;
}

you'll get an error for it, too.

Upvotes: 1

Related Questions