0

I know that the default value for reference types is null and the default value for value types follow this table: http://msdn.microsoft.com/en-us/library/83fhsxwc.aspx.

I also know that in C#, instance fields are automatically initialized and local variables are not. I'm also aware that the compiler will force you to assign a local variable before you read it.

I'm curious about what is the value of a local variable before it's assigned. Is it set to the default value, even though the compiler wants you to explicitly assign a value, or is it just random bits?

Andre Pena
  • 56,650
  • 48
  • 196
  • 243
  • 3
    C# disallows reading unassigned local variables, so the question is moot. – Raymond Chen Jun 19 '14 at 13:22
  • 2
    @RaymondChen: Why? Learning how things work under the hood is always interesting. – jgauffin Jun 19 '14 at 13:30
  • 1
    @RaymondChen One could inspect it using `unsafe` code, not that there would ever be a reason to. – Servy Jun 19 '14 at 14:01
  • The language specification spells out the default value for static variables, instance variables, and array elements, but is silent on the default value for local variables. Therefore, the value is implementation-dependent. – Raymond Chen Jun 19 '14 at 16:05

1 Answers1

7

It actually depends on an IL flag. The MS C# compiler currently always sets this flag, so the memory is actually set to zero. However, technically there is no reason for it to do so. Either way, it is an implementation detail: you cannot find the answer to this using just C#, since C# will not allow you to query the value (directly or indirectly) of a local that is not "definitely assigned" (but you can if you use ILGenerator or similar to create a method directly in IL).

The flag specifically is the init in .locals init (...)

Edit: clarification - the CLI specification requires that all verifiable methods have .locals init, not just .locals: so without this, the code would not be verifiable, even if it was correct.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Thanks for your reply. When you say `set a flag`, do you mean assign a value to the variable, or is it different? What is a flag? – Andre Pena Jun 19 '14 at 13:26
  • 1
    @Andre The C# is compiled to IL; locals are declared in IL at the start (before the body), via either `.locals init (...)` or `.locals (...)` - at least, in text renderings. In *actual bytes*, this is the flag `0x4` in the method header. The presence of this flag (`init` or `0x4`) instructs the JIT to emit instructions to zero the memory of the locals. So it is the JIT, not the C# compiler, that actually produces the instructions to zero the memory. – Marc Gravell Jun 19 '14 at 13:29
  • 1
    @AndréPena see also: http://stackoverflow.com/questions/17645487/how-to-understand-these-paragraphs-in-emca-335-regarding-locals-init – Marc Gravell Jun 19 '14 at 13:29
  • You could use `unsafe` code to get a pointer to an uninitialized local using purely C# code, without writing any IL, not that there is any real reason to want to do so. – Servy Jun 19 '14 at 14:01
  • @Servy `unsafe` is *basically* a catch all "to hell with the rules" *anyway*; but yes, something like: `int i;int* p = &i;int j = *p;` – Marc Gravell Jun 19 '14 at 14:05
  • @MarcGravell Yes, I realize almost all, "you can't do that in C#" questions really need to have a "without unsafe code" clause, for exactly the reason you stated, but then again, so is direct editing of IL. Just pointing out that there is a way. – Servy Jun 19 '14 at 14:09