IanG on Tap

Ian Griffiths in Weblog Form (RSS 2.0)

Blog Navigation

April (2018)

(1 item)

August (2014)

(1 item)

July (2014)

(5 items)

April (2014)

(1 item)

March (2014)

(1 item)

January (2014)

(2 items)

November (2013)

(2 items)

July (2013)

(4 items)

April (2013)

(1 item)

February (2013)

(6 items)

September (2011)

(2 items)

November (2010)

(4 items)

September (2010)

(1 item)

August (2010)

(4 items)

July (2010)

(2 items)

September (2009)

(1 item)

June (2009)

(1 item)

April (2009)

(1 item)

November (2008)

(1 item)

October (2008)

(1 item)

September (2008)

(1 item)

July (2008)

(1 item)

June (2008)

(1 item)

May (2008)

(2 items)

April (2008)

(2 items)

March (2008)

(5 items)

January (2008)

(3 items)

December (2007)

(1 item)

November (2007)

(1 item)

October (2007)

(1 item)

September (2007)

(3 items)

August (2007)

(1 item)

July (2007)

(1 item)

June (2007)

(2 items)

May (2007)

(8 items)

April (2007)

(2 items)

March (2007)

(7 items)

February (2007)

(2 items)

January (2007)

(2 items)

November (2006)

(1 item)

October (2006)

(2 items)

September (2006)

(1 item)

June (2006)

(2 items)

May (2006)

(4 items)

April (2006)

(1 item)

March (2006)

(5 items)

January (2006)

(1 item)

December (2005)

(3 items)

November (2005)

(2 items)

October (2005)

(2 items)

September (2005)

(8 items)

August (2005)

(7 items)

June (2005)

(3 items)

May (2005)

(7 items)

April (2005)

(6 items)

March (2005)

(1 item)

February (2005)

(2 items)

January (2005)

(5 items)

December (2004)

(5 items)

November (2004)

(7 items)

October (2004)

(3 items)

September (2004)

(7 items)

August (2004)

(16 items)

July (2004)

(10 items)

June (2004)

(27 items)

May (2004)

(15 items)

April (2004)

(15 items)

March (2004)

(13 items)

February (2004)

(16 items)

January (2004)

(15 items)

Blog Home

RSS 2.0

Writing

Programming C# 5.0

Programming WPF

Other Sites

Interact Software

So What Exactly Is a Variable?

Thursday 29 January, 2004, 02:49 PM

In a recent blog, I left a conundrum. If you have some code in which a variable holds a string, I asked:

...there are two things: a string and a variable referring to the string. The type of the string itself it obvious: System.String. But what exactly is the variable, according to the .NET type system?

The volume of responses leads me to one of two possible conclusions: (1) nobody cares, or (2) not having a comments facility on your blog seriously reduces your chances of getting feedback even if you do give people your email address.

However, I did get two responses... The first was short and to the point:

Isn't the variable simply a reference to the CLR object header and type handler?

Roughly speaking, yes. But that's really an answer to the question "How is the variable implemented?" I was asking a slightly different question - how is the variable represented in the .NET type system? It clearly isn't a thing of type System.String, because that's the type of the thing it refers to. The string is not the variable. So this answer wasn't really getting involved with what I thought was the interesting part.

But I also got a response from Steve Maine. I won't put our entire conversation up, because there turned out to be quite a lot of it, but I've selected the parts that I believe give us the essence. (And I apologise to Steve if my editing is too agressive.) Given the example:

string foo = "Hello, world";

Steve said that:

Both sides are System.String. The trick is that System.String is a reference type, which means there is an implied level of indirection built into the type. The RHS is a just a constant reference to constant memory, while the LHS is non-const. No matter how you slice it, both sides are managed references.

I disagreed. I didn't think the left hand side was actually a managed reference. So I replied:

...when used in an lvalue context (amongst others), variables are not in fact expressions whose type is a managed reference. We know this because expressions that evaluate to a managed reference aren’t valid lvalues. If they were, this would be legal:

new object () = new object ();

But that’s not allowed. So while there are some syntactic contexts in which a variable does just mean a managed reference, this evidently isn’t one of them.

Steve then replied:

So, syntactically, we can say that variables are typed lvalues. There are other language elements that are also typed but are not lvalues – so the “lvalueness” of a variable is one of its defining features.

Looking at the runtime, specifically in regard to reference types:

As far as the CLR goes, a variable is a named, typed location in memory that can hold data. The runtime ensures that data that’s incompatible with the declared type of the variable will never get stored in that location. A variable of a reference type is basically a managed pointer, in the sense that it’s always sizeof( ptr ) bytes and stack-allocated. It’s assigned a pointer into the managed heap where the real object lives. However, you can never get the address of the real object without dropping into unsafe code. However, if you do that you’re no longer using managed references and are now using pointers.

That's my emphasis there by the way. Now I felt we were getting somewhere. I also felt that now was an appropriate time to let on that I don't actually feel I know the answer to this one... Indeed I believe there isn't a good answer, unless you consider this to be a good answer:

It depends on what you mean by 'the type system'.

The thing is, there doesn't actually seem to be just one type system in the CLR. At last count, I reckoned there were at least four, and they can be described, somewhat approximately, thus:

  1. The intrinsic IL types. By this I mean the type system you get to use in IL instructions. (See Partition I of the CLI spec for more details, and Table 1 for a list of the types in this type system.)
  2. The evaluation stack type system. Bizarrely enough, this isn't actually quite the same as the previous one. (See Partition I of the CLI spec for more details, and Table 6 for a list of the types in this type system.)
  3. The metadata type system. By this I mean what you get to use when defining types. (Although strictly speaking, you also use this one when declaring your local variables to IL.)
  4. The verifier type system. This is the set of rules imposed by the verifier.

Of course that's just at the level of the CLR. (And indeed the CLI.) If you start taking languages other than IL into account it gets yet more complex. The C# type system is essentially a mixture of (3) and (4), unless you run with /unsafe, in which case you get to ignore (4) if you want.

So, bearing that in mind, what is a variable? It is, as Steve says, a named location - when you declare a function, you get to list the local variables it uses. You can declare variables as having any type that can be represented in what I'm calling the the metadata type system (3). However, when you manipulate it, you'll either be using (1) or (2). In (1) the variable looks and behaves a lot like a value type, and if it's declared to be of reference type, then the variable itself is an instance of the IL intrinsic type object. This type doesn't really have a direct representation in the CLR type system. (The CLI specs claim that it's equivalent to System.Object, but those live on the heap, and this clearly doesn't - it's a reference to a thing that can live on the heap. And it can legally have a value of null, which objects on the heap cannot.) This type really only exists in (1) and (2). (In (2) the type goes by the name of O.) Reflection is really just concerned with (3), which is why variables don't show up in the reflection API.

This is a somewhat oversimplified description, mostly because I feel I've gone on quite long enough already. Consult the CLI specs for the full gory details. My main goal was to highlight the fact that things are a little more complex than C# makes them seem. As always, until I get round to adding a comment facility to my blog engine, feel free to respond to me via email.

Copyright © 2002-2024, Interact Software Ltd. Content by Ian Griffiths. Please direct all Web site inquiries to webmaster@interact-sw.co.uk