Take the 2-minute tour ×

This week I've been working on some reflection-based code, and during unit testing found an unexpected condition: pointers are reference types. The C# code typeof(int).MakePointerType().IsClass returns true.

I checked in my just-arrived Annotated CLI Standard, and sure enough, pointers are clearly defined as reference types.

This was surprising to me, coming from a C++ background. I had just assumed that pointers would be value types.

Is there a particular reason why pointer types are reference types and not value types?

Update (clarification)

When talking about pointers and references, things often get confusing regarding the "pointer" and "pointee". So here's some clarification.

Types can be reference types or value types, but variables are a bit different. (Sorry, I haven't had a chance to read through my CLI Standard, so the terminology and concepts may be wrong - correct me, please!)

Given this code (local variable concepts for reference types):

var x = new MyClass();
var y = x;

The variables x and y are not actually reference types, but they're references to an object that is a reference type (MyClass is a reference type). In other words, x and y are not instances of the reference type; they only refer to an instance of reference type.

Given this code (local variable concepts for value types):

var x = 13;
var y = x;

The variables x and y are instances value types (or at least act like they're instances).

So then we come to this code:

var i = 13;
var x = &i;
var y = x;

If the pointer type is a reference type, then this is how I interpret the statement x = &i:

  1. An instance of type int* is created, pointing to i.
  2. Since pointers are reference types, this instance is created on the heap (assuming that all reference types are placed on the heap, an implementation detail).
  3. x is a reference to this pointer instance.
  4. The pointer instance will eventually be garbage collected, just like other reference types.
  5. When y = x is executed, the reference is copied. Both y and x refer to the same instance of the pointer object.

Perhaps I'm completely wrong in this interpretation.

Coming from a C++ background, it would make more sense to me for pointers to be value types, so the statement x = &i is just assigning the address of i to the instance of the value type x, and y = x copies that address value into y. No "pointer object" would be created on the heap.

share|improve this question
From the CLR docs on Type.IsClass - 'Gets a value indicating whether the Type is a class; that is, not a value type or interface'. Technically, a pointer type does not inherit off System.Object, so it not an object, value type or interface, but is a class according to the docs. –  thecoop Jul 23 '10 at 11:26

5 Answers 5


seems there is a distinction.

share|improve this answer
Right; it's possible to determine whether a reference type is a pointer or not. My question is why pointers are reference types and not value types (see updated question). –  Stephen Cleary Jul 23 '10 at 13:13
The CLR differentiates managed and unmanaged pointer types, see of Partition I in the clr spec. Managed pointers may be changed (moved) by the GC. I think this may be the reason for them beeing Class types. –  MaLio Jul 23 '10 at 13:50
See also section 14.4 Partition II - Special Types / Pointer Types –  MaLio Jul 23 '10 at 13:57
up vote 2 down vote accepted

I haven't seen a complete answer, so I'm closing this question down for now.

I'm forced to conclude: pointers (e.g., int *) are actually value types; the fact that their Types return true for IsClass is a mistake in the specification. I suspect that no one has noticed this because getting the type of a pointer is a very rare operation.

share|improve this answer
Have you seen the docs? According to it: In an unsafe context, a type may be a pointer type, a value type, or a reference type. So can't you treat them as neither value type nor reference type? –  nawfal May 13 '13 at 11:47
That makes sense. But it doesn't answer my question: why are pointers reference types (i.e., they return true from IsClass)? –  Stephen Cleary May 13 '13 at 11:55
See the graphic for yet another contradictory statement from docs. Pointers are listed under reference types. –  nawfal May 14 '13 at 10:15

This is just a theory, but would it have something to do with the fact that because of the garbage collection system and heap compaction, pointers have to be adjusted when objects are moved around in memory. By making managed pointers reference types, they can be re-pointed in the same way that any other reference is, rather than having to make them a special case.


An excellent article by Wesner Moise: "Pointers UNDOCUMENTED".

In the article he describes how managed pointers are adjusted during heap compaction.

share|improve this answer
I believe pointers can only point to pinned objects - see MSDN ref. I'll read that article though; looks interesting! –  Stephen Cleary Jul 23 '10 at 13:26

They're reference types because they don't contain the actual value of the target object: just like references, they merely "point to" the target object.

share|improve this answer
I've updated the question to be more clear on reference types vs. reference variables. –  Stephen Cleary Jul 23 '10 at 13:14


MyClass x = new MyClass();

Here, MyClass is a reference type, and if you looked through reflection, x would be called a reference type. But, under the hood, x is actually a pointer.

share|improve this answer
A pointer type (int*) is a completely different entity to a normal object reference –  thecoop Jul 23 '10 at 11:28
@thecoop a reference is conceptually nothing different than a pointer. Both contain the address in memory of some other data, be it an int primitive or a MyClass object. The main difference is that references are typically immutable (the references themselves, not what they refer to). –  corsiKa Jul 23 '10 at 11:54

Your Answer


