Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the C# compiler crash on this code?

Tags:

c#

csc

Why does the code below crash the .NET compiler? It was tested on csc.exe version 4.0.

See e.g. here for online demo on different version - it crashes in the same manner while it says dynamic is not supported https://dotnetfiddle.net/FMn59S:

Compilation error (line 0, col 0): Internal Compiler Error (0xc0000005 at address xy): likely culprit is 'TRANSFORM'.

The extension method works fine on List<dynamic> though.

using System; using System.Collections.Generic;  static class F  {     public static void M<T>(this IEnumerable<T> enumeration, Action<T> action){}      static void U(C.K d) {         d.M(kvp => Console.WriteLine(kvp));     } }  class C  {     public class K : Dictionary<string, dynamic>{} } 

Update: this doesn't crash the compiler

static void U(Dictionary<string, dynamic> d) {     d.M(kvp => Console.WriteLine(kvp)); } 

Update 2: the same bug was reported in http://connect.microsoft.com/VisualStudio/feedback/details/892372/compiler-error-with-dynamic-dictinoaries. The bug was reported for FirstOrDefault, but it seems the compiler crashes on any extension method applied to class derived from Dictionary<T1,T2>, where at least one of the parameter types is dynamic. See an even more general description of the problem below by Erik Funkenbusch.

Update 3: another non-standard behaviour. When I try to call extension method as a static method, that is, F.M(d, kvp => Console.WriteLine(kvp));, the compiler doesn't crash, but it cannot find the overload: Argument 1: cannot convert from 'C.K' to 'System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string,dynamic>>'

Update 4 - SOLUTION (kind of): Hans sketched 2nd workaround, which is semantically equivalent to original code, but works only for extension method call and not for standard call. Since the bug is likely caused by the fact that the compiler fails to cast class derived from generic class with multiple parameters (with one being dynamic) to its supertype, the solution is to provide an explicit cast. See https://dotnetfiddle.net/oNvlcL:

((Dictionary<string, dynamic>)d).M(kvp => Console.WriteLine(kvp)); M((Dictionary<string, dynamic>)d, kvp => Console.WriteLine(kvp)); 
like image 238
Franta Avatar asked Jun 21 '14 19:06

Franta


People also ask

Why does the C exist?

The letter c was applied by French orthographists in the 12th century to represent the sound ts in English, and this sound developed into the simpler sibilant s.

Does the letter C need to exist?

This is a very important rule considering about 25% of words in our language contain a C.] So why do we need a C? When we combine the C with an H we DO make a unique sound. Without a C we would go to Hurch instead of Church, we would listen to a Hime instead of a Chime, etc.

Why does C have the sound of S?

Here's the rule: When 'c' comes directly before the letters 'e', 'i' or 'y' we use the /s/ sound. in other cases we use a /k/ sound.


2 Answers

It is dynamic that is triggering the instability, the crash disappears when you replace it by object.

Which is one workaround, the other is to help it infer the correct T:

static void U(C.K d) {     d.M(new Action<KeyValuePair<string, dynamic>>(kvp => Console.WriteLine(kvp))); } 

The feedback report that you found is a strong match, no need to file your own I'd say.

like image 194
Hans Passant Avatar answered Oct 20 '22 22:10

Hans Passant


Well, the answer to your question as to WHY it crashes the compiler, it's because you've encountered a bug that.... crashes the compiler.

The VS2013 compiler says "Internal Compiler Error (0xc0000005 at address 012DC5B5): likely culprit is 'TRANSFORM'", so clearly it's a bug.

C0000005 is typically a null pointer, or referencing unallocated, or deleted memory. It's a general protection fault.

EDIT:

The problem is also present in pretty much any kind of multiple parameter generic type where the any parameter is dynamic. For instance it crashes on:

List<Tuple<string, dynamic>>{} 

It also crashes on

List<KeyValuePair<dynamic, string>>{} 

But does not crash on

List<dynamic>{} 

but does crash on

List<List<dynamic>>{} 
like image 39
Erik Funkenbusch Avatar answered Oct 21 '22 00:10

Erik Funkenbusch