Home > C#, lambdas > Pointers to Value-Types in C#

Pointers to Value-Types in C#

C# has an "unsafe" mode in which real, nasty pointers are allowed, but this mode is rarely used except in some messy situations involving talking to old code. The C# language proper does not have pointers.

In C and C++, you can get the address of anything, including a local variable on the stack:

int x = 0;

int *p = &x; /* get address of x */

*p = 5; /* change value of x */

Of course, when a function exits, all its local variables cease to exist. Any remaining pointers to them are now "dangling" and must not be used. If they ever are… well, who knows what could happen? Make no mistake, it’s an exciting world of opportunities and I’ve already had plenty of it, thanks.

Naturally we’re all very happy not to have such nonsense in C#. But in fact, thanks to anonymous delegates, we can sort of almost do the same thing anyway. But without the undefined behaviour.

Here’s the Ptr<T> generic class, which is a pointer – or at least can be a pointer if you construct it the right way:

public class Ptr<T>
    Func<T> getter;
    Action<T> setter;

    public Ptr(Func<T> g, Action<T> s)
        getter = g;
        setter = s;

    public T Deref
        get { return getter(); }
        set { setter(value); }

And here’s how to use it:

int x = 0;

Ptr<int> p = new Ptr<int>(() => x, v => x = v); // &x

p.Deref = 5; // *p = 5

Debug.Assert(p.Deref == 5); // *p == 5

In practice it’s a good deal more flexible than a C/C++ pointer. When we construct it, we get to specify exactly how to get or set the value, so there are an unlimited number of possible behaviours, but if we want pointer-like behaviour, we just need to replicate the pattern shown above, providing a getter that maps no arguments onto the variable’s value, and a setter than maps one argument onto the assignment operation.

Using the pointer to modify or obtain the pointed-to value is much simpler. Instead of putting an asterisk in front, we put .Deref on the end.

It’s tempting to think we could add another constructor like this:

public Ptr(ref T x)
    getter = () => x;
    setter = v => x = v;

… which would allow this:

Ptr<int> p = new Ptr<int>(ref x);

But lambdas are not allowed to refer to ref parameters.

I find it interesting that, thanks to anonymous delegates,  C# already contains the plumbing necessary to implement the & (address-of) operator. It could in theory be done as mere syntactic sugar:

Ptr<int> p = &x;

… which would expand to this:

Ptr<int> p = new Ptr<int>(() => x, v => x = v);

Nothing else is really needed.

(Although to be honest, in the year or so I’ve been using C# in earnest, I haven’t ever needed to take the address of a local value-type.)

Categories: C#, lambdas Tags: ,
  1. Colin Eberhardt
    May 29, 2009 at 9:03 am

    Very neat …. I like it🙂

  2. Spencer
    October 1, 2009 at 8:47 pm

    I’m using:
    public delegate T getter();
    public delegate void setter(T value);
    instead of:
    Func getter;
    Action setter;
    but the idea is the same.

    I know this article is old, but mind adding an example on how to implement:
    Ptr p = &x;


  3. earwicker
    October 1, 2009 at 9:09 pm

    Sorry if the article was misleading, but it isn’t possible to make the &x syntax produce a working Ptr. You have to write a lambda that refers to x. The compile silently rewrites your code so that the lambda body is a method in an auto-generated class, and x becomes a field in that class (instead of a local variable on the stack).

    In my post I was just suggesting that in theory the language could be enhanced to have a purely safe version of pointer-to-local semantics, with a little syntactic sugar to expand &x into the required lambda stuff.

  4. August 16, 2016 at 9:14 am

    In order to avoid code duplication, it would probably be possible to construct one delegate from the other delegate using expression trees. Here is an example of how to parse a “getter” delegate passed into a method: http://stackoverflow.com/questions/1402803/passing-properties-by-reference-in-c-sharp/1403036#1403036 (“3. LINQ Expression”). But I agree that pointers to local variables are probably rather interesting theory than something which can be used in practice🙂

    • earwicker
      August 16, 2016 at 10:16 am

      The problem with that is it’s not much better than the reflection example – the caller could pass a lambda that involves any expression of type string (x => "Bad") and there is nothing at compile time to check that it is a simple property with a setter. Rather than using the language properly, we’re just bypassing it.

      This is possibly a demonstration of why languages should support more flexible ways to extend the syntax (i.e. a proper macro system) because if you don’t provider users with a good way to do what they want to do, they’ll go ahead and invent a bad way!

  1. April 27, 2014 at 10:04 pm

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Get every new post delivered to your Inbox.

Join 26 other followers

%d bloggers like this: