4

I read this question in C, and I have the same question in C#.

Is it correct to say that by the code

int a;

four unassigned bytes is reserved for a before it is initialized? Or initialization is where the bytes are allocated for the first time?

4
  • 2
    if it is not assigned any value in program, it will be optimized(thus removed) by clr, you can check that in IL generated Commented Aug 30, 2015 at 11:23
  • Where is this code placed? Inside a method? In a class or struct? Is there any lambda using a ? You are asking about an 'implementation detail' and there is no simple answer. Commented Aug 31, 2015 at 9:51
  • inside a function as in the link. Commented Aug 31, 2015 at 10:18
  • We shouldn't need a link to understand a question. Commented Aug 31, 2015 at 17:47

4 Answers 4

5

An int declaration without assignment will (as mentioned in the comments) will be optimized away by the compiler- it will not show up at all in the program.

Assuming you are in a function (as opposed to a type definition) and assign the int, the allocation will take place from stack space when the function begins (that is, the int is allocated from memory already dedicated to that thread, and will not result in a OS allocation).

On the other hand, if the int is part of a type definition (and is used) then it will increase the allocated space of each instance of that type, wherever that type ends up being allocated (heap for classes, heap or stack for structs depending on usage).

In no situation will it result in a pointer or reference for the int itself.

Some further explanation:

Th original question refers to an int by example. An int is a fixed-length (4-byte) data structure, so the compiler notes that the method containing the declaration in question will be needing 4 bytes to store it. Rather than allocating those 4 bytes on the heap (where it puts reference types) and incurring garbage collection overhead, the compiler will reserve 4 bytes in the area of memory reserved for the current thread's method local variables (the call stack). That memory had been allocated from the OS when the thread started and it is reserved for that thread alone. If the thread runs out of that space, it's called a stack overflow.

It's worth noting here that .NET really has 2 compilers- the C# compiler that converts C# code into IL, and the JIT compiler that converts IL into machine instructions at runtime. In my answer when I say "the compiler", I am doing some hand-waving about which compiler I mean exactly, but the result is the same.

As per the comments, if I do this...

void Foo() {
  {
    int a = 5;
    Console.WriteLine(a);
  }
  {
    int a = 7;
    Console.WriteLine(a);
  }
}

... then it is possible that the compiler could re-use the stack space allocated for the first variable a for the second, as they are semantically different. But that's an optimization.

It's also worth noting that the call stack includes other information besides method-local variables- it includes the parameters to the method, space for the return value (a pointer if the function returns a reference type), and the return address as well.

Finally, I'd add that in C# your methods may be inlined by the JIT compiler- this means that the code of a called method may be copied wholesale into the body of the caller to avoid the overhead of a method call. In that case, the stack frame will include space for the called method's local variables as well.

Sign up to request clarification or add additional context in comments.

7 Comments

I'm not sure if you have answered the question that declaration is the point where allocation takes place or initialization? Is there a specification which answers this question or it depends on the compiler?
I answered it very specifically. The point at which allocation takes place depends on the context of the declaration- if it is in a method for instance, allocation takes place from the thread's stack memory when the stack frame is created (just before the method begins execution).
So do you mean when a function begins, the first thing done is to allocate memory for all declarations found inside the function blocks? Isn't it more correct to say that when any block begins the allocations take place?
Just before the function begins to run. The first thing that the runtime does is to allocate all of the space that the function needs for it's local variables. Then execution is passed into the function. See en.wikipedia.org/wiki/Call_stack
@Minimus Heximus - this is provable because, at the start of a method, it is legal in unsafe code to take the address of any of its variables (even if they have not been initialized).
|
2

An int in C# is always 4 bytes (no matter what the value).

Remember that

int a;

is the same as

int a = 0;

When declaring an int, it is given the default value of 0.

2 Comments

int a = 0; is the same as int a = new int() but it's not the same as int a.
It will still contain a reference though no matter what the value is.
2

Well, It depends on the variable type.
Since int is a ValueType it allocates all 4 bytes needed. There are two main categories of variables in c# : Reference Types and Value Types.In case of value Types such as int all the memory needed for the variable allocates but when you declare a variable of a reference type before using new operator it just allocates a pointer and after creating the main object it allocates the space needed for storing the variable.

Class MyType
{
...
}

MyType s; // Just a pointer
s=new MyType(); //Now allocating happens.

For more information on Reference Types see MSDN Reference Types.
For more information on Value Types see MSDN Value Types.

MSDN :

There are two kinds of types in C#: reference types and value types. Variables of reference types store references to their data (objects), while variables of value types directly contain their data. With reference types, two variables can reference the same object; therefore, operations on one variable can affect the object referenced by the other variable. With value types, each variable has its own copy of the data, and it is not possible for operations on one variable to affect the other (except in the case of ref and out parameter variables, see ref (C# Reference) and out parameter modifier (C# Reference)).

2 Comments

How about int as in the question?
@MinimusHeximus Since int is a ValueType it allocates all 4 bytes needed.
-3

A simple declaration of a variable like in your example will contain a reference, until you create an object with new keyword.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.