Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where in memory are nullable types stored?

Tags:

c#

.net

nullable

This is maybe a follow up to question about nullable types.

Where exactly are nullable value types (int?...) stored in memory? First I thought it's clear enough, as Nullable<T> is struct and those are value types. Then I found Jon Skeet's article "Memory in .NET", which says:

Note that a value type variable can never have a value of null - it wouldn't make any sense, as null is a reference type concept, meaning "the value of this reference type variable isn't a reference to any object at all".

I am little bit confused after reading this statement. So let's say I have int? a = null;. As int is normally a value type, is it stored somehow inside struct Nullable<T> in stack (I used "normally" because I don't know what happens with value type when it becomes nullable)? Or anything else happens here - perhaps in heap?

like image 531
Ondrej Slinták Avatar asked May 19 '10 12:05

Ondrej Slinták


People also ask

Where do we use nullable type?

You typically use a nullable value type when you need to represent the undefined value of an underlying value type. For example, a Boolean, or bool , variable can only be either true or false . However, in some applications a variable value can be undefined or missing.

What are nullable data types?

The Nullable type allows you to assign a null value to a variable. Nullable types introduced in C#2.0 can only work with Value Type, not with Reference Type. The nullable types for Reference Type is introduced later in C# 8.0 in 2019 so that we can explicitly define if a reference type can or can not hold a null value.

In which way do we declare nullable variable?

You can declare nullable types using Nullable<t> where T is a type. Nullable<int> i = null; A nullable type can represent the correct range of values for its underlying value type, plus an additional null value. For example, Nullable<int> can be assigned any value from -2147483648 to 2147483647, or a null value.

What happens when we box or unbox nullable types?

When the nullable type is boxed, the underlying value type is stored in the object, rather than an instance of the nullable type itself. For example, if we box int?, the boxed value will store an int.


1 Answers

First off, Nullable<int> is just a shorthand for something like:

struct Nullable<T>  {     bool hasValue;     T value; } 

Plus all the constructors, accessors, and so on. That's all it is -- a nullable int is an ordinary int plus a flag that says whether the int is null or not. All the rest is compiler magic that treats "null" as a valid value; all "null" does with a nullable type is makes you one of those structs with the flag set to false.

So now that we have that out of the way, your question is "where do they go in memory"? They go the same place that any other structs go in memory: where the runtime and compiler believe to be the best place given the lifetime of the memory.

Most structs go on the heap. Anyone who tells you that "structs always go on the stack" doesn't actually know what they are talking about; our documentation does not say that and it is not true. Structs only go on the temporary memory pool, aka "the stack", when they are local variables or temporaries, and the local variables are not closed-over outer variables of an anonymous method or lambda, and the local variables are not in an iterator block. All other structs go on the heap in our implementation.

Note also that there is no requirement whatsoever that an implementation of the CLI use "the stack" to make their temporary pool. The classic JScript memory manager, for example, stores its temporary pool on the heap. (Though of course the JScript runtime engine is not an implementation of the CLI; I'm merely pointing out that one can design a managed runtime engine that puts no user data whatsoever on "the stack".) Logically it is a stack data structure, but that data structure is not store on "the" stack, it's just a stack structure allocated on the heap.

I have to ask: why do you care? The CLR manages memory on your behalf. Why do you care where nullable types go? They go where they live long enough to be useful to you; you don't have to worry about that.

like image 144
Eric Lippert Avatar answered Sep 18 '22 19:09

Eric Lippert