[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

microsoft.public.dotnet.framework

cs0165 - the error that keeps on giving

ritterhaus

4/18/2008 11:43:00 PM

I'm an unashamed C coder learning C#, and in my first 24 hours with
the language I've already found my first TIDL (thing I don't like),
the inane "error cs0165." I'm sure that this has been discussed and
argued over at great length, but I'm having trouble finding useful
information about why this is considered to be an error and not a
warning. The compiler is often not bright enough to account for the
application logic (flow analysis my eye) and I find that perfectly
valid, error-free pieces of code refuse to compile because C# thinks
I'm too stupid to assign to a local variable before I use it.

The fact is, in my very first C# program (rewriting one of the C
examples I teach with in class) I get this error in two places: both
times the code is perfectly good and the variables hold proper values,
but csc doesn't seem to think so. If this would compile with merely a
warning I could live with that, because unassigned variables are a
Very Bad Thing, but to stop the compile for spurious problems based on
faulty flow analysis seems to me to be overkill.

Is there any intelligent reason for this design, or any intent to
change it in the future? I don't like stray pointers any more than the
next guy, but by gum, when I assign to my variables I don't expect to
be told that they are "unassigned" by some lazy compiler that won't do
as its been told.

RR
3 Answers

Peter Duniho

4/19/2008 12:22:00 AM

0

On Fri, 18 Apr 2008 16:42:43 -0700, <ritterhaus@yahoo.com> wrote:

> [...]
> Is there any intelligent reason for this design, or any intent to
> change it in the future? I don't like stray pointers any more than the
> next guy, but by gum, when I assign to my variables I don't expect to
> be told that they are "unassigned" by some lazy compiler that won't do
> as its been told.

You didn't post a code sample to illustrate what you think is an erroneous
report of this error. However, I'll make the assumption that you've got
some code that you know for sure will get through at least one path that
will initialize a variable, but the compiler isn't noticing it.

I reported this as a bug long ago, was told it's "by design". The C#
specification has a lengthy description of the exact definition of
"definitely assigned" and variables that are used at some point before
they have become "definitely assigned" cause this error to be emitted.

It's been awhile since I looked at this, but my recollection is that
nothing in the spec precludes the compiler detecting more complex cases.
However, the usual argument in favor of keeping it simpler is that,
well...keeping things simpler makes it easier on the compiler writer,
which in turn helps make it more likely that the compiler will be bug-free.

For me, the inconvenience of having to assign variables isn't such a big
deal. My concern is that I think it's a very good idea for the compiler
to treat unassigned variables as a bug, but forcing the programmer to
assign variables to some default value that should never actually be used
winds up with the potential for obscuring an actual "unassigned variable"
bug.

But I also can see the value in keeping the rules for definite assignment
simple, and not requiring the compiler to do logical analysis of the
code. I can't say I'm 100% happy about the current implementation, but I
also wouldn't go ranting about it either. It's not really an issue worth
getting your shorts in a twist over, though a nice calm discussion could
be fine. :)

For what it's worth, you're right that this has been discussed in the
past. Here's one such discussion:
http://groups.google.com/group/microsoft.public.dotnet.languages.csharp/browse_thread/thread/d4d1ba5038c874b1/e537af...

Pete

ritterhaus

4/19/2008 3:00:00 AM

0

On Apr 18, 7:22 pm, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:

> You didn't post a code sample to illustrate what you think is an erroneous
> report of this error. However, I'll make the assumption that you've got
> some code that you know for sure will get through at least one path that
> will initialize a variable, but the compiler isn't noticing it.

True. I said I had two instances of this error borrowed from an old C
program. Here they are:

int input;
System.Console.Write("\nEnter a number: ");
while (true){
try{
input = int.Parse(System.Console.ReadLine());
break;
} catch {}
}
if (input > 0 && input < 10) System.Console.WriteLine("\nYou entered
{0}\n\n.", input);

Now, I don't want input to be initialized to zero; in fact, I want it
to have no value at all unless explicitly assigned by the user, so
input can ONLY be zero if the user entered zero. Initializing the int
to a default value makes no sense in the program's logic. And note
that the statement that accesses the variable is "unreachable" until
input is assigned, so this is NOT an unassigned variable.

Also:

string verb;
int year = 2000, thisYear = 2008;
// get proper verb tense
if (year < thisYear) verb = "was";
if (year == thisYear) verb = "is";
if (year > thisYear) verb = "will be";
System.Console.WriteLine("\nThat {0} a very good year.\n\n", verb);

In this instance verb MUST be assigned because the three if statements
account for all possible values of year. When the WriteLine is called,
verb will always be assigned.

> I reported this as a bug long ago, was told it's "by design". The C#
> specification has a lengthy description of the exact definition of
> "definitely assigned" and variables that are used at some point before
> they have become "definitely assigned" cause this error to be emitted.

So perhaps I disagree with the standard's definition of "definitely
assigned." I can buy that, as I tend to be pretty opinionated and
stubborn (after all, I'm still using C, right?)

> For me, the inconvenience of having to assign variables isn't such a big
> deal. My concern is that I think it's a very good idea for the compiler
> to treat unassigned variables as a bug, but forcing the programmer to
> assign variables to some default value that should never actually be used
> winds up with the potential for obscuring an actual "unassigned variable"
> bug.

I think that that is my point exactly. In my source code, initialized
variables imply some default value that may (or must) be used in
absence of any other value. This same program uses:

bool nan = true;

because my intent is for all user input to be treated as NAN until
some condition exists to explicitly change that. In this case, it
makes sense to initialize the variable. I suppose my beef is that I am
being forced by the compiler to make my code LESS clear (to me,
anyway) so that it can be MORE SURE that I didn't do something
brainless. Which takes me back to the original thought of a compiler
warning. Yes, I've written my share of bugs because I didn't
initialize a variable, but it was never THAT big of a deal: a quick
run or two through the debugger and it becomes pretty obvious. If the
compiler flagged these instances as a POSSIBLE problem I could check
them out, determine that they are fine, and move on. The fact that the
compiler refuses to compile working code disturbs me more than a
little.

> But I also can see the value in keeping the rules for definite assignment
> simple, and not requiring the compiler to do logical analysis of the
> code. I can't say I'm 100% happy about the current implementation, but I
> also wouldn't go ranting about it either. It's not really an issue worth
> getting your shorts in a twist over, though a nice calm discussion could
> be fine. :)

Agreed, and a compiler warning would be great. I for one actually read
all those warnings messages. Just my two cents.

RR

Peter Duniho

4/19/2008 4:00:00 AM

0

On Fri, 18 Apr 2008 20:00:23 -0700, Robert <ritterhaus@yahoo.com> wrote:=


> On Apr 18, 7:22 pm, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
> wrote:
>
>> You didn't post a code sample to illustrate what you think is an =

>> erroneous
>> report of this error. However, I'll make the assumption that you've =
got
>> some code that you know for sure will get through at least one path t=
hat
>> will initialize a variable, but the compiler isn't noticing it.
>
> True. I said I had two instances of this error borrowed from an old C
> program. Here they are:

Well, interestingly neither of the examples you showed are really the be=
st =

way to do things in .NET anyway. We can refactor the code so that it no=
t =

only reads better (at least in my opinion), but it also avoids the CS016=
5 =

error. Specifically:

> while (true){
> try{
> input =3D int.Parse(System.Console.ReadLine());
> break;
> } catch {}
> }

Can instead be:

while(!int.TryParse(Console.ReadLine(), out input))
{
}

Because "out" parameters are required to be assigned before the method =

returns, that satisfies the assignment requirement for the variable =

"input".

And:

> if (year < thisYear) verb =3D "was";
> if (year =3D=3D thisYear) verb =3D "is";
> if (year > thisYear) verb =3D "will be";

Can instead be:

if (year < thisYear)
{
verb =3D "was";
}
else if (year =3D=3D thisYear)
{
verb =3D "is";
}
else
{
verb =3D "will be";
}

You should be using if/else if anyway, because if you satisfy one =

condition, you have no need to check the others. But beyond that, by =

providing a final conditionless "else", the compiler can tell for sure =

that after that section of code, the variable "verb" will be definitely =
=

assigned.

> [...]
>> For me, the inconvenience of having to assign variables isn't such a =
big
>> deal. My concern is that I think it's a very good idea for the compi=
ler
>> to treat unassigned variables as a bug, but forcing the programmer to=

>> assign variables to some default value that should never actually be =
=

>> used
>> winds up with the potential for obscuring an actual "unassigned =

>> variable"
>> bug.
>
> I think that that is my point exactly. In my source code, initialized
> variables imply some default value that may (or must) be used in
> absence of any other value.

I'm not sure how this is your point with the code examples given :), but=
I =

would agree that as a general issue it is in fact a problem with the =

current C# implementation (if not the specification).

> [...] The fact that the
> compiler refuses to compile working code disturbs me more than a
> little.

Well, in the end, it comes down to what's _provable_ by the compiler, =

given a specific set of rules. It's true that the rules could be more =

complicated than they are now, and thus would allow more true things to =
be =

provably true.

But it's a fundamental limitation of logic that not all true statements =
=

are provable. So eventually, we'd run into _some_ barrier anyway. :) =
=

The C# designers just chose to put that barrier a little closer to the =

trivial than you or I would have preferred.

And for what it's worth, the rules regarding definite assignment aren't =
=

actually all that trivial. On the one hand, I think that as complex as =
=

they are, I'm not really sure why they didn't go the extra mile to deal =
=

with this sort of thing. On the other hand, I can see the point of =

someone who feels that they are already complicated enough and that they=
=

shouldn't be made even more complicated.

> Agreed, and a compiler warning would be great. I for one actually read=

> all those warnings messages. Just my two cents.

Well, it _does_ need to be an error. The whole point is the be absolute=
ly =

sure that you're never using any variables that haven't been assigned. =
=

This is both a code correctness and data security issue, and it's a =

critical feature of C#.

So, we could argue in favor of more complicated definite assignment rule=
s, =

but we can't argue in favor of reducing lack of definite assignment to a=
=

warning. It has to be an error. The compiler will not let you execute =
=

code that it cannot prove to itself is safe (according to its own rules =
of =

"safe", of course...you can write code that will erase your hard drive, =
=

and the compiler's happy to let you :) ).

Pete