What is the value for local variables before the assignment? - c#

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?

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.

Related

Why is the int default value not taken during runtime? [duplicate]

Why must I initialize variables inside methods?
int test1; // Not initialized, but OK
public int Foo()
{
int test2; // Not initialized
int test3 = test1; // OK
int test4 = test2; // An error
}
Fields are automatically initialized to the logical zero for the type; this is implicit. Variables must obey "definite assignment", so must be assigned before they can be read.
ECMA 334v4
§17.4.4 Field initialization
The initial value of a field, whether
it be a static field or an instance
field, is the default value (§12.2) of
the field’s type. It is not possible
to observe the value of a field before
this default initialization has
occurred, and a field is thus never
"uninitialized".
and
§12. Variables
...
A variable shall be definitely assigned (§12.3) before its
value can be obtained.
...
Extending Mark's answer, local variable initialization is also related to the verification process.
The CLI requires that in any verifiable code (that is, modules that didn't explicitly asked to skip the verification process using the SkipVerfication property from the SecurityPermission attribute), all local variables must be initialized before their usage. Failing to do so will result in a VerficationException being thrown.
More interestingly, is that the compiler automatically adds the .locals init flag on every method that uses local variables. This flag causes the JIT compiler to generate code that initializes all of the local variables to their default values. Meaning, even though you have already initialized them in your own code, the JIT will comply with the .locals init flag and generate the proper initialization code. This "duplicate initialization" doesn't effect performance since in configurations that allow optimizations, the JIT compiler will detect the duplication and effectively treat it as "dead code" (the auto-generated initialization routine will not appear in the generated assembler instructions).
According to Microsoft (also, backed up by Eric Lippert in response to a question on his blog), on most occasions, when programmers don't initialize their local variable, they don't do so because they rely on the underlying environment to initialize their variable to their default values, but only because they "forgot", thus, causing sometimes-illusive logical bugs.
So in order to reduce the probability for bugs of this nature to appear in C# code, the compiler still insists you will initialize your local variables. Even though it's going to add the .locals init flag to the generated CIL code.
A more comprehensive explanation on this subject can be found here: Behind The .locals init Flag
It actually shouldn't. Your error should be on the second line, not the first, and should be because you used it before you initialized it.
The compiler is helping you here.
So don't initialize them as a habit. Instead let the compiler help you out!
The nice thing about this is that it will path check for you. If you have a switch statement with three cases where each sets the value, but you forget to set it in your "default", but use it afterwards, it will warn you that you missed a path.
If you initialize variables to = 0, you take that benefit away.
As Marc indicates, that's what the specification says. The reason this is a good thing is that there are some valid reasons to leave a member uninitialized rather than a local variable, whose lifetime is bounded by the method it is in. Mostly you'd only ever want this for performance reasons, if the variable is expensive to initialize, and should only be initialized under specific usage scenarios. For my part, I'd avoid uninitialized members until my back was truly against the wall, though!
For local variables, it is also much easier to detect whether all code paths are likely to lead to initialization, whereas there are no good heuristics to determine whether all code paths across the entire programme guarantee initialization before use. A completely correct answer is impossible in both cases, as all computer science students should know.

What does .Net do when you declare an object without an instance?

I wonder to know how the .Net Framework handles the declared but not instantiated object situation.
For example i declare an object like
DropDownList ddl;
and do nothing about it. I know that i should do something with this variable and get a warning about it, but what i don't know is the where it will be stored.
Is there a lookup table that stores the data of all declared variables? Or is there a virtual reference for every declaration?
Edit : I just wanted to know how the memory allocated for this object declaration.
Edit2 : Whether it's a local variable or not, i'm just talking about the memory allocation structure. I wonder to know where this references stored.
If ddl is a field, then the value of ddl will be null, as it is a reference type.
Any attempt to call a member on it will result in a NullReferenceException.
If it is a local variable it will simply be unassigned.
Value types will get the default(T) of their type.
The compiler itself may remove the call completely, depending on where it was declared, but this is an implementation detail.
If you are talking about a local variable then the compiler can simply optimize it out of existence since noone can be using it (if you attempted to use it without initializing the compiler would have protested with an error). In fact the .NET 4 compiler did this for me when I tested just moments ago.
If you are talking about a field in a class then it is initialized with the default value for its type as part of the object construction.
From your description, it sounds like you're talking about a local variable. When you declare a local variable in usual implementations and without any optimizations, then space is reserved for it on the stack (most probably), with a null reference as its value.
You could look into the StackFrame class if you want to inspect further (I've never used it).
The variable is stored in your assembly. It will always have it's default value null.
In release mode (compiler is set to optimize) it's optimized and it is not stored anywhere.
If you want to know more about IL and how the compiler works, wikipedia has a good article to start.
All variables are stored into a class or method. Variables declared into a class can be listed using .NET Reflection :
class Class1 { private int i; public string s; }
typeof(Class1).GetFields(BindingFlags.Instance); // returns all instance fields
typeof(Class1).GetFields(); // returns all instance public fields
typeof(Class1).GetProperties(); // returns all instance public properties
Variables declared into a method cannot be inspected with .NET Reflection mechanisms.

Why are static fields null by default?

Just curious, from the code below I can see that static field of type A will be null by default while variable of that type needs to be initialized to ahve at least null value. Could anyone explain the difference a bit more? Thanks
class Program
{
static A _a; //it is null by default
static void Main(string[] args)
{
A nonStaticA; //empty reference, exception when used
A correctA=null;
}
}
class A
{
}
The initial value of a field, whether it be a static field or an instance field, is the default value of the field's type. It is not possible to observe the value of a field before this default initialization has occurred, and a field is thus never "uninitialized".
If a static constructor exists in the class, execution of the static field initializers occurs immediately prior to executing that static constructor. Otherwise, the static field initializers are executed at an implementation-dependent time prior to the first use of a static field of that class.
A local variable is not automatically initialized and thus has no default value. For the purpose of definite assignment checking, a local variable is considered initially unassigned.
The difference is between local variables and fields, not between static and instance.
Local variables of any type are required to be initialized to a value before they are used the first time. This prevents bugs where you forget to initialize a variable.
The compiler can verify this, because local variables only exist inside a single method, and code in a method is executed in a predictable order, from the top town. So it is easy to check if a variable is accessed before it is initialized.
Fields are different. They can be accessed in multiple methods, and there is no way the compiler can determine in which order they are executed. Therefore it cannot check at compile-time that fields are initialized before they are accessed. Instead fields are given a default value, which is null for all reference types, 0 for integers and so on.
It has nothing to do with static. Class fields (instance and static) are initialized to their defaults, local variables are not.
And why? Like lots of things it was a design decision at some point.
C#, as far as I can observes, kept many things as they were in other previous languages, mainly C++.
The reason in C++ (which may or may not be relevant to C#) is that static (or global) objects are statically written into the executable or library while for other objects the code that creates the object (and not the object itself) is written into the executable or library. For objects on the stack usually code that subtracts some value from the stack pointer is written.
When the executable or library is loaded into memory by the OS the static fields are just a bunch of bytes that are copied as is into memory (the data segment of the process). Since they are copied as is, they already have a value (the value in the executable or library file). Because of that there is no performance implications to setting it to a specific value. For that reason (as far as I can see) the C++ standard made their value deterministic (if they are not initialized explicitly) and what is more natural than zero as an initialization value?!
In order to initialize a dynamic object (whether it is on the stack or the heap) code has to be inserted into the executable or library. This has performance implications (and maybe other implications) so the C++ standard preferred to leave it up to the programmer.
I'm not completely sure every bit of this data is true, but it is what seems logical to me from what I know.

Unassigned value error in C#

if variable is not assigned, then it takes the default value at run time.
for example
int A1;
if i will check the value of A1 at runtime it will be 0;
then why at compile time it throws a error of unassigned value;
why CLR don't use to a lot the default value at runtime;
int A1;
int B1 = A1+10;
it should be 11 as the default value of A1 is 0;
there project property where i can check for "assign default values for unassigned variable";
Can anybody tell me where i can find it?
Your statement
if variable is not assigned,then it takes the default value at run time
is only true for member variables in a class.
For local variables inside a function, this is wrong. Local variables inside a function always require initialization.
it should be 11 as the default value of A1 is 0;
This is exactly the reason that the C# compiler won't let you get away with using uninitialized variables. The result would be 10, not 11. After a good 30 years of experience with C and C++, languages that allow you to use uninitialized variables, the C# team decided that this was a major source of bugs and to not allow this in a C# program.
There are lots of little tweaks like this. Another great example is not allowing fall through to another case in a switch statement. Forgetting to write break is such a classic bug. Outlawing these C-isms is rather an excellent idea and a big part of why C# is such a great language. Unless you dislike the idea of a compiler as a police officer.
Fwiw: using an uninitialized variable is permitted in VB.NET.
Default value is true for class members, but not for function locals. Whatever code you put directly into an as[pc]x file, the code generator will put it into a function.
Most of the time this happens is because the variable is an Object and before you can use it you need to Instantiate it.
When you assign a String = "" this is instantiated for you
You are talking about local variables or class level variables ? The rules are different for both. Check our Jon Skeet's reply at this:
Initialization of instance fields vs. local variables
The heap (reference classes) and the constructor for structs zero's the data.
Simple value-types like int, but also references (=pointers) to objects, do not get a default value on the stack. You should always set it. If this was not mandatory, specially with object-pointers, this could be a major security breach, because you are pointing to unknown locations.
Any default value (like 0) would probably be wrong 50% of the time.

Why must local variables have initial values?

Why must I initialize variables inside methods?
int test1; // Not initialized, but OK
public int Foo()
{
int test2; // Not initialized
int test3 = test1; // OK
int test4 = test2; // An error
}
Fields are automatically initialized to the logical zero for the type; this is implicit. Variables must obey "definite assignment", so must be assigned before they can be read.
ECMA 334v4
§17.4.4 Field initialization
The initial value of a field, whether
it be a static field or an instance
field, is the default value (§12.2) of
the field’s type. It is not possible
to observe the value of a field before
this default initialization has
occurred, and a field is thus never
"uninitialized".
and
§12. Variables
...
A variable shall be definitely assigned (§12.3) before its
value can be obtained.
...
Extending Mark's answer, local variable initialization is also related to the verification process.
The CLI requires that in any verifiable code (that is, modules that didn't explicitly asked to skip the verification process using the SkipVerfication property from the SecurityPermission attribute), all local variables must be initialized before their usage. Failing to do so will result in a VerficationException being thrown.
More interestingly, is that the compiler automatically adds the .locals init flag on every method that uses local variables. This flag causes the JIT compiler to generate code that initializes all of the local variables to their default values. Meaning, even though you have already initialized them in your own code, the JIT will comply with the .locals init flag and generate the proper initialization code. This "duplicate initialization" doesn't effect performance since in configurations that allow optimizations, the JIT compiler will detect the duplication and effectively treat it as "dead code" (the auto-generated initialization routine will not appear in the generated assembler instructions).
According to Microsoft (also, backed up by Eric Lippert in response to a question on his blog), on most occasions, when programmers don't initialize their local variable, they don't do so because they rely on the underlying environment to initialize their variable to their default values, but only because they "forgot", thus, causing sometimes-illusive logical bugs.
So in order to reduce the probability for bugs of this nature to appear in C# code, the compiler still insists you will initialize your local variables. Even though it's going to add the .locals init flag to the generated CIL code.
A more comprehensive explanation on this subject can be found here: Behind The .locals init Flag
It actually shouldn't. Your error should be on the second line, not the first, and should be because you used it before you initialized it.
The compiler is helping you here.
So don't initialize them as a habit. Instead let the compiler help you out!
The nice thing about this is that it will path check for you. If you have a switch statement with three cases where each sets the value, but you forget to set it in your "default", but use it afterwards, it will warn you that you missed a path.
If you initialize variables to = 0, you take that benefit away.
As Marc indicates, that's what the specification says. The reason this is a good thing is that there are some valid reasons to leave a member uninitialized rather than a local variable, whose lifetime is bounded by the method it is in. Mostly you'd only ever want this for performance reasons, if the variable is expensive to initialize, and should only be initialized under specific usage scenarios. For my part, I'd avoid uninitialized members until my back was truly against the wall, though!
For local variables, it is also much easier to detect whether all code paths are likely to lead to initialization, whereas there are no good heuristics to determine whether all code paths across the entire programme guarantee initialization before use. A completely correct answer is impossible in both cases, as all computer science students should know.

Categories

Resources