Pseudonymous
Pseudonymous

Reputation: 884

What does the stack entry for a reference type contain?

I'm refreshing my memory on how reference and value types work in .NET. I understand that the entry on the stack for a reference type contains a pointer to a memory location on the heap. What I can't seem to find details about is what else the stack entry contains. So, given the following:

Customer customer;
customer = new Customer();

After the first line of code an entry on the stack containing a null pointer will exist. Does that entry also contain the identifying name "customer"? Does it contain type information?

Have I fundamentally misunderstood something?

Upvotes: 6

Views: 534

Answers (3)

Hans Passant
Hans Passant

Reputation: 941605

Only the pointer to the object is stored, nothing else. Not on the stack, it is stored in a processor register. Only if the method is large and the register is better used for other purposes will it be stored on the stack. Making that the decision is the job of the optimizer. Which is in general fairly unlikely to happen since you'll probably be using properties and methods of the Customer class so keeping the pointer in a register is efficient.

This is otherwise the basic reason why a NullReferenceException can tell you nothing useful about what reference is null. Associating the pointer value back to a named "customer" variable can only be done by a debugger. It needs the PDB file to know the name of the variable, that name is not present in the metadata of the assembly. Which is the basic reason why you cannot use Reflection to discover local variable names and values.

And this is also why debugging only works well when you use it on the Debug build of your project. That disables the optimizer and gets the pointer value to always be stored back to a stack slot, allowing the debugger to reliably read it back. At a significant cost, the basic reason you should only ever deploy the Release build of your project.

Upvotes: 11

Zein Makki
Zein Makki

Reputation: 30032

1- Variable names are not stored in memory along with the reference.

2- A null reference doesn't store the type of the object.

Example to make things clear:

string str = null;

if(str is String)
{
    Console.WriteLine("I'm a string");
}
else
{
    Console.WriteLine("I'm not a string");
}

// This will print: "I'm not a string"

You're actually telling the compiler, allow me to create only string references using the mapped storage location by str.

Variables represent storage locations. Every variable has a type that determines what values can be stored in the variable

Upvotes: 2

Marco7757
Marco7757

Reputation: 764

The variable name customer does only exist in the source code (as it is of no interest to your computer). During runtime, nobody knows how the variable was called in the code.

Jon Skeet wrote a good article about what is stored on the heap and what goes to the stack. The first paragraph (what's in a variable?) should answer your question:

The value of a reference type variable is always either a reference or null. If it's a reference, it must be a reference to an object which is compatible with the type of the variable. For instance, a variable declared as Stream s will always have a value which is either null or a reference to an instance of the Stream class. (Note that an instance of a subclass of Stream, eg FileStream, is also an instance of Stream.) The slot of memory associated with the variable is just the size of a reference, however big the actual object it refers to might be. (On the 32-bit version of .NET, for instance, a reference type variable's slot is always just 4 bytes.)

Upvotes: 2

Related Questions