If you've
read blog for a while, you must know about the myth that "Value Types go on the Stack". Also
there are plenty of examples that reinforce the same. But I don't agree with
the same because:-
1.
The statement should be value types can be stored on the stack, instead of the more common "value types are always stored on the stack".
2.
It is almost always irrelevant.
In some languages, you must know whether a particular storage is on the
stack or the heap for correctness reasons.
3.
It is incomplete. What
about references?
References are neither value
types nor instances
of reference types, but they are values. They've got to be stored
somewhere. Do they go on the stack or the heap? Why does no one ever talk about
them? Just because they don't have a type in the C# type system is no reason to
ignore them.
The real
statement should be "In the Microsoft implementation of C# on the
desktop CLR, value types are stored on the stack when:”
o Value is a local variable or temporary that is not a closed-over local
variable of a lambda or anonymous method
o The method body is not an iterator block, and the jitter chooses to not
enregister the value.
The sheer number of weasel words in
there is astounding, but they're all necessary
§ Versions of C# provided by other vendors may choose other allocation
strategies for their temporary variables; there is no language requirement that
a data structure called "the stack" be used to store locals of value
type.
§ We have many versions of the CLI that run on embedded systems, in web
browsers, and so on. Some may run on exotic hardware. I have no idea what the
memory allocation strategies of those versions of the CLI are. The hardware
might not even have the concept of "the stack" for all I know. Or
there could be multiple stacks per thread. Or everything could go on the heap.
§ Lambdas and anonymous methods hoist local variables to become
heap-allocated fields; those are not on the stack anymore.
§ Iterator blocks in today's implementation of C# on the desktop CLR also
hoist locals to become heap-allocated fields. They do not have to! Other implementations
are also possible. Microsoft could have chosen to implement iterator blocks as
co-routines running on a fiber with a dedicated stack. In that case, the locals
of value type could go on the stack of the fiber.
§ People always seem to forget that there is more to memory management
than "the stack" and "the heap". Registers are neither on
the stack or the heap, and it is perfectly legal for a value type to go in a
register if there is one of the right sizes. It is important to know when
something goes on the stack, then why isn't it important to know when it goes
in a register. Conversely, if the register scheduling algorithm of the JIT
compiler is unimportant for most users to understand, then why isn't the stack
allocation strategy also unimportant?
It is
simply false that the choice of whether to use the stack or the heap has
anything fundamentally to do with the type of the thing being stored. The truth is: the choice
of allocation mechanism has to do only with
the known required lifetime of the storage.