Fog Creek Software
Discussion Board




Welcome! and rules

Joel on Software

Why is Use of unassigned local variable an error?

I can still use an unassigned public variable (field) which is not considered an error, but should be if things were consistent.

I think unassigned vars in C# is just fine, as they have all a default value.

Thomas Eyde
Wednesday, October 08, 2003

All developers treat warnings as errors, so what's the difference, right? :)

Brad Wilson (dotnetguy.techieswithcats.com)
Wednesday, October 08, 2003

Thomas, think: how is the compiler going to know if some other code (perhaps external) won't have assigned a value to a field? Therefore it can't be sure whether or not the field will have been explicity assigned a value from somewhere. Now, with local variables where the scope is so much tighter, the compiler *can* deduce whether a value will have been assigned at any particular point - so the C# language designers decided that the more explicit they could make your code, was the best option. I agree with them.

Incidentally, IL does allow you to use an unassigned local variable, maybe that's the language you'd prefer ;-).

Duncan Smart
Wednesday, October 08, 2003

I have thought about it. I think rules should be consistent; here the rule is sometimes you can use an unnasigned variable, sometimes you can't. And what's the point of default values if I can't use them (locally)?

And as you said, the local scope is much tighter, so if my code does the wrong thing it is easier to spot that unassigned.

Unassigned variables have never been a problem in all my years as a VB programmer, so why should it now? This is C/C++ paranoia where unassigned variables is not defined.

This rule is enforced where you don't need it, but not where you need it because the compiler can't. I say they should skip the rule all together.

Thomas Eyde
Thursday, October 09, 2003

Huh? It is consistent:

When the compiler can detect something almost guaranteed to be cause problems, it complains.
When the compiler has no way to know if something is an error, it says nothing.

True, you can write code so that today it happens to work right. But tomorrow, when the code is re-ordered or a line is added, it won't work. This is a real and very common situation. So note the warning and future-proof your code today.

mb
Saturday, October 11, 2003

Consistency is obviously in the eye of the beholder.

But is it always an error when the compiler can't decide? How often have you experienced bugs caused by uninitialized variables in a language which assigns well known default values?

As I wrote earlier, in VB6 this was never a problem. And if the function is so large you can't easily spot a wrong/missing assignment, then you probably have more serious problems than unassigned variables.

Thomas Eyde
Sunday, October 12, 2003

I future-proof my code with unit tests. I don't need unassigned variable errors.

Thomas Eyde
Sunday, October 12, 2003

That's like saying I protect my network with a firewall, I don't need virus software or software firewalls.

One tool protects you against large ranges of error, but it's not the whole story. In the unitiailized variable case, typically it bites you as a bug with input you hadn't thought of/tested with.

BTW, I tend to treat this warning similar to what you say: if I ever see the warning, it's probably time to refactor the function, it may have too many unrelated branches in it.

And does C# or the CLR define what the unintiailized value is? I don't know; I guess that VB turns 'dim x' into the equvalent of 'object x = null', you just have to add the '=null' explicitly yourself in C#--another difference in the language.

mb
Sunday, October 12, 2003

Examples, please. You all tell me how dangerous an unassigned variable is, yet I see no examples or stories.

I understand why unassigned variables don't work in C/C++ where they are undefined. But that's not the case with C#; here an unassigned variable has a defined, default value.

Thomas Eyde
Sunday, October 12, 2003

What is the default value? according to

http://msdn.microsoft.com/library/en-us/csref/html/vcrefdefaultconstructors.asp

"Remember that using uninitialized variables in C# is not allowed."

Wether or not you agree with this decision (obviously the VB.Net designers do not), there is no default value for a stack variable. Which makes sense, since all variables in C# are really pointers (I think), which means you'd have an int which is null, which isn't quite how most people think of them.

On the other hand, member values are all set to 'zero', which also makes sense, since when you say new whatever, some code (the constructor) gets run, and so the language is nice and pre-sets everything to zero.

As for a typical error case, I don't have one off the top of my head. Typically it's just a missed case. Also, you can also 'fix' this problem by scoping your variables more tightly.

mb
Sunday, October 12, 2003

In the context of member variables, the default value for a reference type is null, and for a numeric value type it's zero. I'm pretty sure that covers everything, because everything else ends up being a composite of numeric value types and reference types.

I could be wrong though. :)

Brad Wilson (dotnetguy.techieswithcats.com)
Monday, October 13, 2003

Strings are an oddball type (where the default is an empty string, at least in VB.NET).

Dave Rothgery
Monday, October 13, 2003

Another thing VB.NET did right (so there are at least two). It's a shame VB.NET did so many wrongs.

The only default value for a string is empty, not null. When I see a string, I expect it to be a string, hence using all string instance methods. But in C#, I have to test for null first. So a C# string actually have two empty values: One when it's nothing (null), another when it also is nothing (empty). Who really care about the technical difference?

Thomas Eyde
Tuesday, October 14, 2003

Since local unassigned is not permitted, their default values can be treated as undefined, which they probably are as I know understand. But the concept of default values are introduced in C#, why not always use them?

And I am still looking for an answer on my question (rephrased a little):

When a language assignes default values to variables, why is the use of an unassigned local variable an error?

It does have a value, and often that value happens to be correct or of no concern.

Here's an example which short cuts the compiler's rule:

    class Properties {
        public string Name;
    }

    public class Person {
        public string GetName() {
            return new Properties().Name;
        }
    }

The GetName is technically, but not logically different from:

        public string GetName() {
            string name;
            return name;
        }

I still don't get it why it should be treated as an error.

Thomas Eyde
Tuesday, October 14, 2003

A last comment (for now). I understand that unassigneds will cause bugs in C/C++ where their default values are random. That means a bug is hard to detect because the bug will also be random.

A signed int will cause problems half of the time when only positives are allowed. A smaller range of permitted values will increase the bug rate, but it will still be random.

This problem does not occure in a language where all variables have a default value.

Thomas Eyde
Tuesday, October 14, 2003

Why do I waste my time on this? I don't know, maybe it has something to do with that I want a fast coding language. I am experienced enough to not have a compiler babysit me with stupid rules (not all rules are stupid).

Why not go for VB.NET? We're not in Kansas anymore, but fast still is. VB.NET is so verbose, that all the fastness is gone.

Then there are all those languages built on the C syntax. And which language does Microsoft use internally? That alone makes me believe more in C# than any other .Net languages.

But C# is too explicit were it doesn't need to. This thread is just one example. I could write another one on meaningless typecasts.

Thomas Eyde
Tuesday, October 14, 2003

"Strings are an oddball type (where the default is an empty string, at least in VB.NET)."

Well, we were talking about C# (where the default value of a string is null, not an empty string). It's too bad VB.NET does that, because I'd consider that at least moderately broken behavior. *shrug*

Brad Wilson (dotnetguy.techieswithcats.com)
Tuesday, October 14, 2003

"So a C# string actually have two empty values: One when it's nothing (null), another when it also is nothing (empty). Who really care about the technical difference?"

That's your interpretation, and you're welcome to it. It's certainly not mine, nor the majority of programmers. There are some very valid reasons for differentiating null ("I didn't not provide a value") from an empty string ("I provided a value, and the value is a string with no text in it").

Brad Wilson (dotnetguy.techieswithcats.com)
Tuesday, October 14, 2003

Eh.

'this makes sense if the default value of a string is an empty string
Dim myString as String
myString &= "some stuff"

// this doesn't make sense if the default value of a string is null, even though it probably works fine
string myString;
myString += "some stuff";

Admittedly, you're going to use a StringBuilder if you're doing a lot of string concatenations anyway, but appending to a null just seems weird.

Dave Rothgery
Tuesday, October 14, 2003

the second example won't work. but

string myString = "";
myString += "some stuff";

works just fine. just like

object myObject = new object(); /* or =null */

work just fine.

C# != VB.NET. Different decisions, it allows and requires more control of these issues.

mb
Tuesday, October 14, 2003

Here comes yet another stupid question: So null are fine on strings because you then can see when a value is provided or not.

Why is this important on strings, but not on the other base types?

And the ASP.NET TextBox.Text is never null. If you assign a null, you get "" back. So how do you know if a value is provided or not? Did the user not type anything, or did he type an empty string?

Thomas Eyde
Thursday, October 16, 2003

the textbox is a ui component, and an ASP textobx is a ui component in a particular pre-existing architecture.

making one which had the concept of 'null' on a different platform (e.g. windows forms) is much easier. you could also do it with an html form, but why?

typically null vs. empty is used elsewhere in the program. let's say you had a web site with session state. then you have something like (this is a really dumb example off the top of my head)

if (session.username == null)
redirect to page which askes user for username

then if the user chooses not to enter anything, you set session.username to "" (zero-length string) and have code like

else if (session.username != "")
print "hello " session.username
else
print "hello anonymous coward"

so, three states: user never got the chance to enter a name, user chose not to enter a name, user entered some name. of course you could handle this with a separate state variable, but why?

now imagine serialiazng this info, using it for something not so trivial, etc.

mb
Saturday, October 18, 2003

I don't like one variable to describle multiple concepts. Here you use the same variable to decide:

  - wether the user is logged in or not
  - is he anonymous or not

You said this was a dumb example. If dumb examples are the only one's we can think of, then allowing a string to be null is perhaps not so smart after all?

And what should I do in a similar case when I use an int UserId instead?

To me it seems that many people choose to interpret a null to mean something special just because they can. A concept can always be implemented in several ways. In this login example, we could:

  - always provide a login button
  - whenever a user name is not provided, the user is anonymous
  - that means anonymous is default

Thomas Eyde
Saturday, October 18, 2003

this isn't a log in scenario, just some sesion state. which can probably be expressed another way.

but a more likely case is a config file. you can have a file which says:

ParentLastName: Smith

Now if ChildLastName is not present, you use parentlastname. If it's blank, you use blank (the guy's an artist and legally changed his name to Prince or something). If it's present (say, Jones), you use that.

Again, 3 states, can be expressed with a separate boolean. Because strings are always a reference type, they're often overloaded for that. You're right it's an overload, but it's a very useful technique because it's needed so often. For something like an integer, you can use a variant to have the same effect-- VT_NULL = not specified, VT_I4 = specieifed.

mb
Sunday, October 19, 2003

It's still about interpretation: What does a null string really mean?

So you are exploiting the fact that a string can be null. Are those designs expressive? Are they obvious? I would never guess that ChildLastName == null means: Now you have to use that other value, ParentLastName (What if the parents have different last names?).

Why not have only LastName, give the child a name at birth and the child change later if he/she is not satisfied.

See? Simpler design, simpler code, no lookup rules, and null is not a part of the equation.

Thomas Eyde
Sunday, October 19, 2003

Let me turn it around on you.

Nulls are a part of the language. Reference types can be null. Why do you rebel against the idea of null strings, when strings are a reference type? Are you against the idea of null, period?

Brad Wilson (dotnetguy.techieswithcats.com)
Sunday, October 19, 2003

I am not against the idea of nulls, I am against strings being null. If we leave out how strings is currently implemented from this discussion, and concentrate on the concept of a string, then in my opinion:

A string is used as if it were a value type, just like ints and bools. Hence it should behave like a value.

But why is it so important that a string can be null while an int can't? Nobody has answered that question yet, and I believe it is because they haven't noticed there is a mismatch between the concept and the implementation.

So maybe the string should be a value, then? Just like the int. Nothing prevents the actual data to be an internal reference.

Thomas Eyde
Tuesday, October 21, 2003

Let's say I accept that a string in concept should be a reference. Then I should handle strings just like my other objects. But I don't:

I don't test my business objects against null to see if it's valid. At this point in my code, a null would be an exception, meaning my code is broken. Null is rarely a valid value.

If I assign the value of one variable to another, I expect my variable to contain an instance of something. That is, not null.

I should reference myString.Value instead of myString.

I should test on myString.IsEmpty instead of myString == "", or the derivatives.

I should always instantiate with new String(something), as no other reference objects has a short hand notation. And it is here, I think, the concept breaks.

Thomas Eyde
Tuesday, October 21, 2003

I think you don't get an answer is probably because most people here don't agree with your point of view.

I however, think String should have a default value and it must be the empty. I spent too much time to write code checking on a string is empty or null. in most cases, the way to handle them are the same. so, why not giving an empty value?

i don't see the value of null when i know the string is empty.

ray
Tuesday, October 28, 2003

*  Recent Topics

*  Fog Creek Home