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.