Tuesday, October 12, 2010

Debunking another myth about value types

Here's another myth about value types that I sometimes hear:
"Obviously, using the new operator on a reference type allocates memory on the heap. But a value type is called a value type because it stores its own value, not a reference to its value. Therefore, using the new operator on a value type allocates no additional memory. Rather, the memory already allocated for the value is used."
That seems plausible, right? Suppose you have an assignment to, say, a field or local variable s of type S:
s = new S(123, 456);
If S is a reference type then this allocates new memory out of the long-term garbage collected pool, a.k.a. "the heap", and makes s refer to that storage. But if S is a value type then there is no need to allocate new storage because we already have the storage. The variable s already exists and we're going to call the constructor on it, right?
Wrong. That is not what the C# spec says and not what we do.
It is instructive to ask "what if the myth were true?" Suppose it were the case that the statement above meant "determine the memory location to which the constructed type is being assigned, and pass a reference to that memory location as the 'this' reference in the constructor". Consider the following class defined in a single-threaded program (for the remainder of this article I am considering only single-threaded scenarios; the guarantees in multi-threaded scenarios are much weaker.)
using System;
struct S
{
   private int x;
   private int y;
   public int X { get { return x; } }
   public int Y { get { return y; } }
Read more: Fabulous Adventures In Coding