4

I am new to programming and this is creating a lot of confusion for me.

Suppose we have the following statement:

Int32 i = 1; 

i's content is stored on memory, which will be four bytes : 00000000 00000000 00000000 00000001

How does CLR access this memory location later? Does CLR store the address to this memory block somewhere?

6
  • It is generally bad practice to use the non-aliased types in c#. Int32 should just be "int" Int64 is "long" Commented Oct 30, 2011 at 17:11
  • 3
    @Mranz Considering that his question is more about the clr than C#, it's probably better to use .NET names instead of C# aliases. Commented Oct 30, 2011 at 17:20
  • @xanatos It is tagged c# Commented Oct 30, 2011 at 17:34
  • 1
    @Mranz And he is using the C# syntax. And that I know :-) In the end you did the right thing telling him that he souldn't normally use Int32, but this was the 1 in 1000 cases where it was ok to use it (because, in the end, the C# specifications don't tell anything about memory) Commented Oct 30, 2011 at 17:44
  • 1
    @Mranz: There are a number of reasons to use the type names instead of the alias keywords, for example whenever you want to emphasize the size of the type, which is common for serialization code for networking and/or interop, in order to yield a specific layout. Commented Oct 30, 2011 at 18:31

4 Answers 4

4

System.Int32 is a value type, no references used.

In fact, a local variable may never be in memory at all, if the compiler can find a CPU register to hold it during its entire life.

If it is in memory, its address will be found by adding an offset to the stack pointer (ESP) or to the address of the reference-typed (class in C#) object that contains it.

In the code generated from the JIT, variables of value types are indistinguishable from variables used by native code (there's no object header or anything like that).

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

Comments

3

The compiler keeps track of where the variable is, so that it can create code that will access it in the right way.

In this case you are declaring a local variable, so it will be allocated on the stack.

The program will not access the variable at a specific address, but as an offset from the base pointer, which points to the stack frame of the current method.

The code to set the variable to 1 can for example look like this when it's compiled into machine code for a 32 bit application:

mov dword ptr [ebp-8],1 

The ebp register points to the top of the stack frame, so the i variable is allocated eight bytes below that in this case.

1 Comment

Thank you. Your answer made it clear to me. I'm going to study how memory stack works.
2

Let's say that NORMALLY, if i is a local variable, it will be saved on the stack. The abstract VM of .NET is a stack based one.

I'll add that on Intel/AMD i won't be saved that way :-) Intel/AMD are little endian. So it will be 00000001 00000000 00000000 00000000

I'm mixing it a little... Now... the IL language and the .NET abstract VM are "pure" stack based, so there is a stack :-) (but there are no registers, so "pure") (I hope you know what a stack is). When the code is JITted to machine code for the computer you are using, probably i will be put in a register or on the stack.

Note that in general it's wrong wrong wrong to say that value types (or non-reference types, if you want to include managed/unmanaged pointers/references) are saved on the stack and/or in registers. They are saved where they are saved. For example value types member of a class are saved with(in) the class (so normally in the heap). Value types in yield functions, in async functions, in "normal" methods but being referenced by "closure type" anonymous functions are normally saved somewhere in the heap. But all these are reference implementations details.

7 Comments

Desktop .NET doesn't have a VM, there is a virtual architecture that MSIL targets, but this architecture isn't implemented. Instead a JIT compiler converts MSIL into native code.
@BenVoigt For VM I meant Virtual Machine not as VMWare but as "Virtual Architecture".
@BenVoigt Wiki calls them Process Virtual Machine
I assumed you meant like a Java virtual machine. But .NET doesn't have one. There is nothing that executes MSIL instructions.
@BenVoigt The first implementations of Mono where interpreted if I remember correctly. The existence or absence of a VM is an implementation detail. In the end you program against this "abstract" machine and then, thanks to Microsoft engineers, your code is compiled instead of being interpreted.
|
0

From what I can tell, actual heap allocated references are stored as double pointers (or some equivalent) so that the garbage collector can move memory without having to affect anywhere in code that something is referenced by updating pointer being pointed to.

6 Comments

The references are (in the current implementation) not double pointers, but direct pointers. The garbage collector does actually update the pointers themselves when it moves an object.
@Guffa That smells like bad implementation to me then, because the GC would have to track all usages of the item, stack and otherwise.
It has to do that anyway, to know which objects are used and which are not.
Only if it isn't using a reference counting mechanism like shared pointers.
It's not using reference counting. This might be informative: stackoverflow.com/questions/867114/…
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.