valentin tihomirov said:
And you respond to my post where I highlight that the only rule which is
need is "(1) never use unassigned vars". It is ultimately simple and easy to
understand.
It's not easy for the compiler to implement, nor for the specification
to make clear what should be allowed at compile time.
Note that there's a difference between "unassigned" and "not definitely
assigned according to the language specification". The compiler
prevents you from using the latter, which in turn always prevents the
former too.
I like languages where the rules are reasonably easy to understand,
even if that means that occasionally I have to spell things out a bit
more for the compiler's benefit.
Again, "Spelling out more" means here: shutting up the compiler checks by
garbage-initializing the vars. This is after you have artificially
overcomplicated your grammar by describing where our trivial rule [1] stops
working. You are happy doing nonsense for less security claming the
opposite.
In some cases, yes. It's far from an "every day" occurrence
I agree that the rare weird garbage initialization is better trade-off than
no cheking at all.
But you would rather see a specification which is insanely complicated?
Exactly how far would you go, anyway? Consider the following program:
using System;
class Program
{
static void Main(string[] args)
{
int x;
if (ReturnTrue())
{
x = 5;
}
Console.WriteLine (x);
}
static bool ReturnTrue()
{
return true;
}
}
Should the compiler have to cope with that case as well, realising that
ReturnTrue() will always return true, and therefore x will always be
assigned a value?
How about:
using System;
class Program
{
static void Main(string[] args)
{
int x;
object o = SomeOtherClass.GetSomeReference();
if (IsNull(o) || !IsNull(o))
{
x = 5;
}
Console.WriteLine (x);
}
static bool IsNull(object o)
{
return o==null;
}
}
Now, *we* can work out that IsNull won't change its return value
between calls, and so it ends up as if (someBool || !someBool) which is
always going to be true, but would you expect the compiler to?
Sooner or later there will always be a boundary which the compiler
can't cross, unless you expect it to effectively solve the halting
problem - at which point I don't even want to *imagine* the spec.
In other words, there's a balance to be made between
compiler/specification complexity and never having to introduce an
assignment just for the sake of the compiler. I think the C# designers
got the balance about right - the spec is reasonably readable, and it
still relatively rarely complains at the wrong time.
Can you list exactly which extra situations you'd include, and which
you'd consider too complicated?