1

In C# I know that if I write into a method a statement like this:

int a; // local variable

then I can't use that before an initialization.

In fact the C# specifications says:

A local variable introduced by a local-variable-declaration is not automatically initialized and thus has no default value

However if I run Visual Studio in debug mode it shows that a has 0 as default value?

Why? May be is it relative to IL code. ?

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
xdevel2000
  • 20,780
  • 41
  • 129
  • 196
  • 1
    I've tried to write a bit in-depth answer a few times, but it's hard to get the right level of detail. All in all, Glorin's answer is completely correct, easily understood and short. Just note that what you see in a debugger is not necessarily what happens when *not* debugging - for example, in a debugger, the lifetime of locals is tied to scope, while the same doesn't apply outside of a debugger (e.g. locals are eligible for collection after they are used for the last time, rather than waiting for the "block" to end). This also includes many differences in stack handling and initialization. – Luaan Nov 11 '15 at 15:10

3 Answers3

4

The fact that you can't use a local before explicit initialization is a rule built into C# to prevent bugs. If you attempt to use a variable that you haven't assigned to, that's very likely to be a mistake.

That the compiler actually initializes locals to their 'zero' or 'null' value is not really relevant. It's not something the compiler needs to do. Probably just something that was simpler on the compiler designers for one reason or another.

Response to edit with spec quote:

I would say that this still complies with the spec, because from within the context of your C# program you cannot observe the variable without initializing it. Thus, in context, it is not initialized. I highly doubt that debugger is really expected to obey the same rules of definite assignment. We know, with the help of the debugger, that it is set to 0 when created. But the compiler also knows that you didn't assign anything to it, and can treat the variable as uninitialized.

Glorin Oakenfoot
  • 2,455
  • 1
  • 17
  • 19
2

An integer is not nullable, it's default value is always 0

Jamiec
  • 133,658
  • 13
  • 134
  • 193
  • 1
    So why can't you access it from code when you don't initialize it? – CodeCaster Nov 11 '15 at 15:03
  • @CodeCaster are you asking another question, or is that a hint that I missed something in this one? – Jamiec Nov 11 '15 at 15:04
  • I find your answer very simplistic, that's why I asked that question. Related: [Why do local variables require initialization, but fields do not?](http://stackoverflow.com/questions/30816496/why-do-local-variables-require-initialization-but-fields-do-not). – CodeCaster Nov 11 '15 at 15:05
  • @jamiec it is asked in the question "Why" it is that he can't use it before initialization (overread it at first myself) – Thomas Nov 11 '15 at 15:06
  • 1
    I see your points, but I read this as `However if I run Visual Studio in debug mode it shows that a has 0 as default value. Why?`. Anyway other answers do a better job of answering this. – Jamiec Nov 11 '15 at 15:15
2

What you are seing is one of the "automatisms" in regards to variables.

Some variables like strings are nullable which means they can have null as value and thus this is the default value for them if they are not initialized.

Other variables like (most) number variables are not nullable and thus can't have null as value. For these variables a different default value is there if they are not initialized. Like for integers 0.

Be aware that with nullable I don't mean the ? variables like int? but really the variable of the type itself if it can have the null value.

The "can't be used before initialization" is a security measure. As normally when you print out a variable that you didn't have set in any way......you get completely junk data (0 for an int, null for others, ...) thus you always should only read from a variable when it has been initialized in some kind. When it is prohibited by regardless what way then you can see this as a security feature.

Edit: To make it a bit more clear "Default" value and "initialized to" is maybe a bit confusing here. It is so that they could have had ANY value, and are just set to what is allowed for them and can represent an invalid state like null for nullable and some other value (in this case 0) for non nullable. In essence these variables are not initialized on purpose on this. They are just seemingly set to a value that is within their range (even though the compiler counts them as uninitialized still).

Thomas
  • 2,886
  • 3
  • 34
  • 78
  • 2
    In short, there's no legitimate reason to read an uninitialized local, so the compiler forbids it - it would always be a mistake. However, that doesn't say that the compiler is forbidden to initialize the local itself, or that the debugger is forced to tell you "UNINITIALIZED!!!". – Luaan Nov 11 '15 at 15:13
  • 1
    Exactky, I would count this uninitialized (and also the compiler message about it) as security features as you never can be sure what value it would have.....and in all honesty if you didn't set it to anything why read it (you are in essence reading just random memory parts then in the worst case) – Thomas Nov 11 '15 at 15:15