C# Structs: Unassigned Local Variable

C# Structs: Unassigned local variable?

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));

Use of unassigned local variable: value type vs custom struct

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.

Compiler complains about unassigned struct variable but allows members to be assigned - why?

You are misunderstanding the error you are getting. Structs are considered to be definitely assigned if all instance fields are definitely assigned. This is perfectly valid:

struct A
{
public int i;
}

A a;
a.i = 1;
Console.WriteLine(a); //no error, a is considered to be definitely assigned.

But this isn't:

struct A
{
public int i;
public int j;
}

A a;
a.i = 1;
Console.WriteLine(a); //a is not definitely assigned because a.j isn't.

The error is similar to the one you get if you do not initialize members inside a custom constructor:

struct A
{
public A(int i)
{
this.i = i;
} //error, j is not assigned.

public int i;
public int j;
}

In your case, MYSTRUCT must have instance fields that are not being correctly initialized or must be initialized through a propery setter.

In short, don't worry about this issue because you can really only initialize value types this way if they:

  1. are mutable
  2. expose directly all instance fields (not through properties)

Both are generally considered bad practices so you should probably run away from any value type you encounter that fit in these two categories.

How to remove compiler error with struct: Use of unassigned local variable

Is there a code way to tell it to shut up and mind its own business?

The compiler's business is implementing the C# specification. The code you've written should not compile according to the C# specification. The s.DoSomething() call is reachable without s being definitely assigned, therefore your code is broken. That's not the compiler's fault. If the Mono compiler used to allow it, that was a bug which has apparently now been fixed.

The simplest way of fixing it is to definitely assign the value, of course:

MyStruct s = new MyStruct(); // Value will never actually be used

There are plenty of cases where we (as humans) can tell that something will never happen, but the compiler can't. Here's another example:

public int Foo(int input)
{
if (input >= 0)
{
return input;
}
else if (input < 0)
{
return -input;
}
// This is still reachable...
}

We know that every int input will go into one of those if bodies, but the compiler will still (correctly) give a compilation error on the above code, because the closing brace is reachable and it's a non-void method.

Your claim that "The code (should be) fully correct" is according to your reasoning, not the C# specificiation... and the compiler is only meant to care about the latter.

One thing to note: the specification doesn't even care about the fact that we do actually set inited to true in some cases. Even if it always had the value of false, it's still just a local variable, not a constant expression. Here's a simple example demonstrating that with no loop:

static void Main()
{
int x;
bool condition = false;
if (condition)
{
Console.WriteLine(x);
}
}

This still gives an error: "error CS0165: Use of unassigned local variable 'x'"

From section 8.7.1 of the C# 5 specification:

The first embedded statement of an if statement is reachable if the if statement is reachable and the boolean expression does not have the constant value false.

Here the expression is condition, which is a local variable. A local variable is not a constant expression in technical terms, even if it will never change. If you make it a local constant instead, it will compile:

static void Main()
{
int x;
const bool condition = false;
if (condition)
{
Console.WriteLine(x);
}
}

Now there's a warning about the body of the if statement being unreachable - but there's no error.

Why is there no Use of unassigned local variable compile error on an empty user defined struct?

Section 5.3 of the C# 5 specification covers this:

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

That's automatically the case when there are no instance variables, hence the variable is considered to be definitely assigned, and can be used in the ToString() call.

Generic class, constraint by struct, generate compile time error Use of unassigned local variable

In the statement

class GenericStruct<T> where T : struct

struct indicates that T is a by-value type.

The type argument must be a value type. Any value type except Nullable can be specified.

So T could be, for example, int. And in such a case the statement

T temp1;

leaves temp1 uninitialized.

C# Beginner - Use of Unassigned Local Variable Issue

The problem is that if product1 does not equal any of the values in your if statements, then none of those sections will ever run, and so in theory there is a danger that price1 might never be given a value. And it can't use something which doesn't have a value to add it to something else. That's what the compiler is complaining about. You need to give price1 a default value when you first declare it, as a fallback option in case the user enters something which is not one of the four expected product names.

double price1 = 0;

Is probably ok for this scenario, but you can choose whatever value you think is best, as long as there is some kind of value.

You will have the exact same issue with price2 as well.



Related Topics



Leave a reply



Submit