I’m not saying it’s a bug; I’m just saying if it’s NOT a bug, then I don’t know what a bug is

Just when I thought I was going to post today about something not-entirely-programming-related, I stumbled across this bizarre bug (or feature?) in the C# compiler.

In a nutshell, allow me to express this anomaly in a trilogy of code snippets. It has to do with using a mutable struct variable in a using statement within which the variable is captured inside a closure. Yes, all three ingredients I just listed are prerequisite for the observation of this behavior.

First Snippet: A mutable struct in a using statement

var list = new List<int> { 1, 2, 3 };

using (var e = list.GetEnumerator())
{
    while (e.MoveNext())
    {
        Console.WriteLine(e.Current);
    }
}

Output

1
2
3

Second snippet: A mutable struct that has been captured inside a closure

var list = new List<int> { 1, 2, 3 };

var e = list.GetEnumerator();
Func<int> closure = () => e.Current;
while (e.MoveNext())
{
    Console.WriteLine(e.Current);
}

Output

1
2
3

So far so good, right? Nothing surprising here. But wait…

Third snippet: A mutable struct in a using statement that has been captured inside a closure

var list = new List<int> { 1, 2, 3 };

using (var e = list.GetEnumerator())
{
    Func<int> closure = () => e.Current;
    while (e.MoveNext())
    {
        Console.WriteLine(e.Current);
    }
}

Output

The above code outputs 0 to the console in an infinite loop! Aaaaaggghhh whyyy?!?

Seriously, I wish I knew. (And if/when I find out, I will definitely let the readers of this blog know.)

Advertisements

4 thoughts on “I’m not saying it’s a bug; I’m just saying if it’s NOT a bug, then I don’t know what a bug is

  1. Christopher says:

    That last snippet should be submitted to Microsoft Connect. The generated IL suggests the correct usage of e is not being maintained. It appears that because e is an outer variable it is placed into a helper class. Being a mutable value type may be what is breaking this.

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

%d bloggers like this: