Wednesday, May 14, 2014

What do types look like underneath the language?

The 1.3 section of the C# 5.0 Language Specification covers types and variables.  In a previous post I went through some of the things about variables, but we didn't look at what the underlying structures are.  CIL is a high level assembly like language that is generally written only by compilers.  The great news is that if you are a compiler writer, CIL has huge levels of abstraction that you don't normally get with assembly.  To demonstrate this, below is a section of code and an associated section of CIL that I generated using JustDecompile.  It is interesting to see the one to one match between C# and CIL.  The one that really surprised me was that Decimal is from MSCorlib, but I guess it shouldn't have.  If you want to see something really cool though, use JustDecompile to look at the regenerated C# code and look at all that the compiler optimized away.

C# Code:
using System;
class Test
{
    enum testEnum { one, two, three }
    struct testStruct { public int x; public testEnum y; public object z; }
    class Stack { };
    interface testInterface { int x { getset; } testEnum y { getset; } object z { getset; } }
    public class testInterfaceInstance : testInterface { int testInterface.x { getset; } testEnum testInterface.y { getset; } object testInterface.z { getset; } }
    delegate int testDelegate(int x, char y);
    static void Main()
    {
        { //Simple Types
            sbyte a;
            short b;
            int c;
            long d;
            byte e;
            ushort f;
            uint g;
            ulong h;
            char i;
            float j;
            double k;
            decimal l;
            bool m;
            a = 1; b = 1; c = 1; d = 1; e = 1; f = 1; g = 1; h = 1; i = '1'; j = 1; k = 1; l = 1; m = true;
        }
        { //Nullable Simple Types
            sbyte? a;
            short? b;
            int? c;
            long? d;
            byte? e;
            ushort? f;
            uint? g;
            ulong? h;
            char? i;
            float? j;
            double? k;
            decimal? l;
            bool? m;
            a = 1; b = 1; c = 1; d = 1; e = 1; f = 1; g = 1; h = 1; i = '1'; j = 1; k = 1; l = 1; m = true;
        }
        { //Enum types
            testEnum a;
            a = testEnum.one;
        }
        { //Nullable Enum types
            testEnum? a;
            a = testEnum.one;
        }
        { //Struct types
            testStruct a;
            a = new testStruct();
            a.= 1;
            a.= testEnum.one;
            a.= "one";
            a.= 1;
        }
        { //Nullable Struct types
            testStruct? a;
            a = new testStruct { x = 1, y = testEnum.one, z = "one" };
        }
        //Reference types
        { // Class types
            object a;
            string b;
            Stack c;
        }
        { //Interface types
            testInterface a;
            a = new testInterfaceInstance();
            a.= 1;
            a.= testEnum.one;
            a.= "one";
            a.= 1;
        }
        { //Array types
            int[] a;
            int[,] b;
            int[][] c;
            a = new int[2];
            a[0= 1; a[1= 2;
            b = new int[22];
            b[00= 1; b[01= 2; b[10= 3; b[11= 4;
            c = new int[2][];
            c[0= new int[2];
            c[1= new int[2];
            c[0][0= 1; c[0][2= 2; c[1][0= 3; c[1][1= 4;
        }
        { //Delegate types
            testDelegate a;
            a = delegate(int b, char c) { return b; };
        }
    }
}

Variable section of the CIL:

No comments:

Post a Comment