2

When I read next book of chapter "Value and reference types" then a question comes to my mind: "When are value types stored in stack"? Cause programmer cannot initialise any value type out of class. Cause when we initialise some variable of value type in class then variable is stored in heap.

My question is: when are value types stored in stack?

StepUp
  • 36,391
  • 15
  • 88
  • 148
  • You should read the chapter again. I'm sure it is explained thoroughly in there somewhere. – Mikael Östberg Aug 22 '13 at 09:09
  • All you will need to know is in this question. Some very good answers. http://stackoverflow.com/questions/4487289/memory-allocation-stack-vs-heap – asafrob Aug 22 '13 at 09:11
  • possible duplicate of [Arrays, heap and stack and value types](http://stackoverflow.com/questions/1113819/arrays-heap-and-stack-and-value-types) – bigge Aug 22 '13 at 09:11
  • As a side-note, I've seen a lot of books *get this wrong*. I've also seen a lot of books get *describing the difference between value-types and reference-types wrong*. So it is entirely possible that the fault here is not you, but the book. I was actually technical editor on a book that made some mistakes here; I pointed out the errors repeatedly, and they weren't rectified - so I had to ask for my name to be removed from the book (I'm not there just to rubber-stamp it!) – Marc Gravell Aug 22 '13 at 09:35

5 Answers5

11

Well, firstly it is very rare that you would need to know, but basically, value-types are stored where-ever they are owned.

They are stored on the stack when they are part of the execution flow of a thread, which can mean:

  • in a "local" (a method variable) - excluding some cases (below)
  • as a floating value in part of a method, i.e. the return value from one method that is about to be passed as a value to another method - no "local" is involved, but the value is still on the stack
    • value-type parameters that are passed by-value (i.e. without ref or out) are simply a special-case of this
  • in an instance "field" (a type variable) on another value-type that is itself on the stack (for the above reasons)

They are stored on the heap (as part of an object) when:

  • in an instance "field" on a class
  • in an instance "field" on a value-type that is itself on the heap
  • in a static "field"
  • in an array
  • in a "local" (a method variable) that is part of an iterator block, an async method, or which is a "captured" variable in a lambda or anonymous method (all of which cause the local to be hoisted onto a field on a class that is generated by the compiler)
  • when "boxed" - i.e. cast into a reference-type (object, dynamic, Enum, ValueType (yes: ValueType is a reference-type; fun, eh?), ISomeInterface, etc)
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • To make it clear, I would add the case of the parameters... But perhaps it's a can of worms... A non-ref non-out value-type parameter? – xanatos Aug 22 '13 at 09:17
  • @xanatos added as a sub-item under "floating value" – Marc Gravell Aug 22 '13 at 09:19
  • For all of your examples where you say that they're on the stack, they may in fact be in a CPU register, instead, mayn't they? – Damien_The_Unbeliever Aug 22 '13 at 09:34
  • @Damien_The_Unbeliever I am limiting my answer here to the IL / CLI level. What the JIT does is entirely up to the JIT. Heck, if you wanted to, I suspect you could write a stackless JIT (like stackless python) – Marc Gravell Aug 22 '13 at 09:37
  • The only way I can get discussions of heap and stack storage to make sense is if we're talking about what's actually happening at runtime, and has to be after JITting has occurred. At the IL level, the only stack that's "in scope" is the evaluation stack, and that's not where local variables are stored. – Damien_The_Unbeliever Aug 22 '13 at 09:50
  • @Damien_The_Unbeliever conceptually, I would say that they are all one and the same: [incoming parameters][locals][evaluation stack] – Marc Gravell Aug 22 '13 at 09:57
  • Do I understand correctly if value type is initialized in class then it is not necessary that value type of class will be dtiredh in heap? – StepUp Aug 22 '13 at 10:46
  • @StepUp a value type is always *initialized* in a **method**. What matters is *what we do next* - for example, is the value assigned to a a field? and if so: of what *type*? I cannot parse "it is not necessary that value type of class will be dtiredh in heap?", so I can't answer that - can you clarify? – Marc Gravell Aug 22 '13 at 10:49
  • sorry for my mistake. Do I understand correctly if value type is initialized ina method of a class then it is not necessary that value type of class will be stored in heap? – StepUp Aug 22 '13 at 11:52
  • @StepUp if you only make use of the value in the method, then in most cases there would be no reason for it to go anywhere near the heap, indeed. The list of things that would cause it to go onto the heap are shown in the answer. – Marc Gravell Aug 22 '13 at 13:35
3

My question is: when are value types stored in stack?

From The Truth About Value Types:

[I]in the Microsoft implementation of C# on the desktop CLR, value types are stored on the stack when the value is a local variable or temporary that is not a closed-over local variable of a lambda or anonymous method, and the method body is not an iterator block, and the jitter chooses to not enregister the value

ta.speot.is
  • 26,914
  • 8
  • 68
  • 96
0

To be precise, the stack and the heap are (or should be) irrelevant in managed environments.

In practice, local variables value types (structs in C#) tend to be allocated on the stack. However, there are cases when they are allocated on the heap instead.

One such case is when they are boxed. Boxing means using an Int32 as an Object, for example by passing it to a method that takes an object parameter. One reason for this is polymorphism: Structs don't carry a vTable pointer and thus cannot do dynamic virtual method resolution (for such methods as ToString(), for example) - but they are sealed, so they can do the resolution statically. On the other hand, if a struct is forced to be stored in an object reference, it needs to be transformed to a heap-allocated vTable-enabled object.

A value type may also be allocated in the heap when it's part of a heap-allocated object - for example, when it's a data member (field) of a class.

Theodoros Chatzigiannakis
  • 28,773
  • 8
  • 68
  • 104
0

Another source of confusion appears to be that you assume reference and value types are 2 types of classes, that is not true

keyword class -> Reference type
keyword struct-> Value type

Karthik T
  • 31,456
  • 5
  • 68
  • 87
0

The first web search hit on your question gives you Eric Lippert's The Truth About Value Types, which starts with the most important part: it is almost always irrelevant. So, why do you want to know? Will you program differently?

Anyway:

The truth is: the choice of allocation mechanism has to do only with the known required lifetime of the storage.

CodeCaster
  • 147,647
  • 23
  • 218
  • 272