tags:

views:

315

answers:

6

I'm reading through Jon Skeet's book reviews and he is going over the numerous inaccuracies of Head First C#.

One of them caught my eye:

[Under Errors Section] Claiming that structs always live on the stack.

In what situations would structs not live on the stack? This goes contrary to what I thought I knew about structs.

+7  A: 

One common example is where the struct is a member of an object that is allocated in the heap. There is lots of additional detail in this question here. What’s the difference between struct and class in .Net?

1800 INFORMATION
but isnt a struct nearly ALWAYS a member of an object that is allocated on the heap? isnt this the case everywhere except when the struct is just a local variable?
Simon_Weaver
Almost everywhere. A struct can also be a static member of a class, in which case it is not a member of an object and is nevertheless allocated on the heap.
Justice
+2  A: 

When the instance of a value type gets boxed, the box, and hence the instance itself, gets moved to the heap. Although, there is got to be no doubting that a non-class member value type instance when first created is always created on the stack.

A struct is a value type. So it behaves as above.

Frederick
The boxed type itself is actually a reference type, mind you. Any value type has a sort of shadowy reference type version for boxing. It's a bit complicated. The "member of a class" case is much less arguable IMO :)
Jon Skeet
+4  A: 

Whenever they are a field on a class

Unusual examples of this:

a: When a value-type variable is captured:

int i = 2;
Action action = delegate {i++;}
action();
Console.WriteLine(i);

This is compiled to something more like:

class Foo {
    public int i;
    public void Bar() {i++;}
}
...
Foo foo = new Foo();
foo.i = 2;
Action action = foo.Bar;
action();
Console.WriteLine(foo.i);

b: When a value-type variable is used in an iterator block:

IEnumerable<int> GetValues() {
   for(int i = 0 ; i < 5 ; i++) yield return i;
}

(the compiler generates a state machine to represent the iterator, of which all local variables (such as i) are fields)

Marc Gravell
+2  A: 

Just as an example of the answer from 1800 INFORMATION:

public class Foo
{
    int x;

    public Foo(int y)
    {
        x = y;
    }
}

...

Foo foo = new Foo(10);

Now, after the constructor has finished executing, the value of foo.x is 10. Where is foo.x in memory? On the heap. What's the type of foo.x? int aka System.Int32, which is a struct.

The other answers about captured variables and boxing etc are correct as well ("sort of" in the boxing case - I'll add a comment), but this example is the most simplest and most important one, IMO.

Jon Skeet
Are all value types structs?
Simucal
There are structs and enums - that's the lot, I believe.
Jon Skeet
.Net is weird. An int is a struct. As a C++ developer, that will take some getting used to
1800 INFORMATION
A: 

Already mentioned in depth by others

  • Member field values
  • boxed structs (strictly they are then no longer value types)

In addition:

  • An array of structs resides entirely on the heap
  • static structs (not on the stack or the heap but in a special area all of their own)
ShuggyCoUk
A: 

Most of the time...

Simon_Weaver
i still think this is actually true :-)
Simon_Weaver