C# 4.0 Compiler Crash
Asked Answered
B

4

50

This code sample is not able to be compiled. Any work arounds out there?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    using church = Func<dynamic, dynamic, dynamic>;

    class Program
    {
        static void Main(string[] args)
        {
            church True = (a, b) => a;
            church False = (a, b) => b;

            Func<church, church, church> And = (x, y) => x(y(True, False), False);
        }
    }
}

Error 6 Internal Compiler Error (0xc0000005 at address 5476A4CC): likely culprit is 'EMITIL'. An internal error has occurred in the compiler. To work around this problem, try simplifying or changing the program near the locations listed below. Locations at the top of the list are closer to the point at which the internal error occurred. Errors such as this can be reported to Microsoft by using the /errorreport option. TestApplication

Brehm answered 25/10, 2011 at 19:18 Comment(1)
It appears to be any generic with "dynamic" in it inside a using statement to create a type alias.Brehm
E
27

I reproduced the crash using VS2010 (WinXP 64).

Two workarounds:

1. don't use the using alias

The following code compiles cleanly on VS2010:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Func<dynamic, dynamic, dynamic> True = (a, b) => a;
            Func<dynamic, dynamic, dynamic> False = (a, b) => b;

            Func<Func<dynamic, dynamic, dynamic>, 
                 Func<dynamic, dynamic, dynamic>,
                 Func<dynamic, dynamic, dynamic> > And 
                = (x, y) => x(y(True, False), False);
        }
    }
}

2. use the Mono compiler

No problem with Mono 2.10 compiler (dmcs).

[mono] /tmp @ dmcs test.cs
test.cs(18,42): warning CS0219: The variable `And' is assigned but its value is never used
Compilation succeeded - 1 warning(s)
[mono] /tmp @ ./test.exe 
[mono] /tmp @ 

This was tested on linux.

  1. You can run binaries created with mono on Windows .NET.
  2. Mono compiler comes with an installer MSI and runs on Windows as well.
Eugeneeugenia answered 25/10, 2011 at 19:22 Comment(0)
O
49

Clearly that is a compiler bug.

I mentioned this to one of our testers and he says:

I’m happy to report that this has already been fixed and you’ll see this fix in the next version of VS. You’ll actually see it fixed in the BUILD Developer Preview for Visual Studio as well!

Apologies for the error, and thanks for bringing this to our attention.

Optician answered 25/10, 2011 at 20:2 Comment(2)
Please note my comment on Jon Skeet's answer: the delegate is irrelevant; using crash = List<dynamic>; will crash as well.Sogdian
@EricLippert The bug is still present in VS 2012 v11.0.61030.00 Update 4Heiner
E
27

I reproduced the crash using VS2010 (WinXP 64).

Two workarounds:

1. don't use the using alias

The following code compiles cleanly on VS2010:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Func<dynamic, dynamic, dynamic> True = (a, b) => a;
            Func<dynamic, dynamic, dynamic> False = (a, b) => b;

            Func<Func<dynamic, dynamic, dynamic>, 
                 Func<dynamic, dynamic, dynamic>,
                 Func<dynamic, dynamic, dynamic> > And 
                = (x, y) => x(y(True, False), False);
        }
    }
}

2. use the Mono compiler

No problem with Mono 2.10 compiler (dmcs).

[mono] /tmp @ dmcs test.cs
test.cs(18,42): warning CS0219: The variable `And' is assigned but its value is never used
Compilation succeeded - 1 warning(s)
[mono] /tmp @ ./test.exe 
[mono] /tmp @ 

This was tested on linux.

  1. You can run binaries created with mono on Windows .NET.
  2. Mono compiler comes with an installer MSI and runs on Windows as well.
Eugeneeugenia answered 25/10, 2011 at 19:22 Comment(0)
R
21

EDIT: I've now managed to reproduce it, and I have a potential workaround.

This works:

csc Test.cs

This doesn't:

csc /debug+ Test.cs

So it looks like it's a problem with the debug information. If you can live without that in your particular scenario, you're good to go...

EDIT: I've just tested, and this happens with /debug:pdbonly as well...

EDIT: Just in case anyone was wondering, I'll ping Eric Lippert about this.

EDIT: This is now the minimal repro I've found:

using church = System.Func<dynamic>;

class Program
{
    static void Main() {}
}
Rouen answered 25/10, 2011 at 19:30 Comment(3)
Sweet find. You can also going without the type alias (using)Eugeneeugenia
I suspect the problem is the implied attributes in the lambda don't have anywhere to go because the lambda isn't actually used; therefore, the next method (in this case Main()) suddenly has an imbalanced stack or something like that. Of course, not actually knowing the compiler's internals it's a wild stab in the dark.Sogdian
Also, we always used delegates but that's irrelevant. using crash = List<dynamic>; will crash as well.Sogdian
S
14

Here's another workaround: don't use Func, use a good old delegate type.

public delegate dynamic Church(dynamic x, dynamic y);

class Program {
    static void Main(string[] args) {
        Church True = (a, b) => a;
        Church False = (a, b) => b;

        Func<Church, Church, Church> And = (x, y) => x(y(True, False), False);
    }
}

This also has the benefit, that Church is defined everywhere, and not just as a per-file using alias.

Sogdian answered 25/10, 2011 at 20:1 Comment(2)
"Don't use Func, use a good old delegate type" <-- last time I checked, Func (including the rest of the Func<T> family) were delegates...Pulido
@larsw: I meant use a non-generic delegate type. As I showed in the example.Sogdian

© 2022 - 2024 — McMap. All rights reserved.