tags:

views:

341

answers:

2

From the documentation:

Unlike classes, structs can be instantiated without using a new operator.

So why am I getting this error:

Use of unassigned local variable 'x'

When I try to do this?

        Vec2 x;
        x.X = det * (a22 * b.X - a12 * b.Y);
        x.Y = det * (a11 * b.Y - a21 * b.X);

Where Vec2 x is a struct?

+5  A: 

Well, are X and Y properties (rather than fields)? If so, that's the problem. Until all the fields within x are definitely assigned, you can't call any methods or properties.

For instance:

public struct Foo
{
    public int x;
    public int X { get { return x; } set { x = value; } }
}

class Program
{
    static void Main(string[] args)
    {
        Foo a;
        a.x = 10; // Valid

        Foo b;
        b.X = 10; // Invalid
    }
}

Is Vec2 your own type? Do you have access to the fields involved, or only the properties?

If it's your own type, I would strongly urge you to try to stick to immutable structs. I know managed DirectX has some mutable structs for getting as close to optimal performance as possible, but that's at the cost of strange situations like this - and much worse, to be honest.

I would personally give the struct a constructor taking X and Y:

 Vec2 x = new Vec2(det * (a22 * b.X - a12 * b.Y),
                   det * (a11 * b.Y - a21 * b.X));
Jon Skeet
Ah, they were properties. Good catch! I'll consider making X and Y private if I can get away with it.
Mark
+1. Nice one, Jon.
Mitch Wheat
+3  A: 

It is still uninitialized. You need to initialize it before using it. You can use default operator for that if you don't want to create a static Vec.Empty value and happy with the defaults for the structs members:

Vec2 x = default(Vec2);

Mitch Wheat:

This, however doesn't:

public struct Vec2
{
    int x;
    int y;

   public float X { get { return x; } set { x = value; } }
   public float Y { get { return y; } set { y = value; } }

}
static void Main(string[] args)
{
    Vec2 x;

    x.X = 1;
    x.Y = 2; 
}

The compiler prevents you from calling propertis on types before all of it's members have been initialized, even though a property might just set one of the values. The solution, as Jon Skeet proposed, is to have an initializing constructor and preferably no setters.

Igor Zevaka