Home

I always wanted to try GPGPU programming but never had the opportunity and doing business applications in .NET doesn’t really helps doing that (still, there are people doing this in high frequency trading applications but that’s not my case).

But for a game, this is completely different.

Read the rest of this entry »

Say you have state defining struct you want to be copy:

 

        public struct MyStruct
        {
            public int A;
        }

Then use it like that:

            var S0 = new MyStruct();
            S0.A = 42;

            var S1 = S0;
            S1.A = 1337;

            Trace.WriteLine(String.Format("S0 = {0}, S1 = {1}", S0.A, S1.A));

The output is: S0 = 42, S1 = 1337
Even though S1 = S0, because it’s a struct it was copied. If I replace struct by class I get S0 = 1337, S1 = 1337. Everything’s normal.

Let say I want to have an array in this struct:

        public struct MyStruct
        {
            // Can't initialize the array directly
            public int[] A;

            // We can't customize the parameterless constructor
            public MyStruct(int size)
            {
                A = new int[size];
            }
        }

        var S0 = new MyStruct(1);
        S0.A[0] = 42;

        var S1 = S0;
        S1.A[0] = 1337;

        Trace.WriteLine(String.Format("S0 = {0}, S1 = {1}", S0.A[0], S1.A[0]));

The output is … S0 = 1337, S1 = 1337
That’s because the reference to the array was copied in the struct, not the actual value.
How can we have the array inside the struct?

        public unsafe struct MyStruct
        {
            public fixed int A[1];
        }

        unsafe static void Main(string[] args)
        {
            var S0 = new MyStruct();
            S0.A[0] = 42;

            var S1 = S0;
            S1.A[0] = 1337;

            Trace.WriteLine(String.Format("S0 = {0}, S1 = {1}", S0.A[0], S1.A[0]));
        }

And I get S0 = 42, S1 = 1337. But there are 2 problems in this approach.

  • You now have to build everything using the unsafe keyword because now A is a int*
  • This works:
                var S0 = new MyStruct();
                S0.A[1] = 42;
    
                var S1 = S0;
                S1.A[1] = 1337;
    
                Trace.WriteLine(String.Format("S0 = {0}, S1 = {1}", S0.A[1], S1.A[1]));
    

    .
    Even though my array is 1 element long, I was able to access the second in-existent element and change it. That’s a buffer overflow: because my array is now unsafe, the runtime no longer checks the boundaries of my array and I can access memory outside my allowed space.

What would be cool is if I was able to write that:

        public struct MyStruct
        {
            // hey C# compiler, create 10 int fields in my struct (from A0 to A9) and translate S0.A[i] to S0.Ai for me
            public int A[10];
        }

Btw I realize this wouldn’t work for some cases like, what should happen if we pass this A as a parameter for a method call expecting a regular array? If we try to store the A in a local int[], what would be in that variable? A new copy of this array? The address of that array in the struct that might be allocated on the stack? How should we track that reference?

But anyway, we can dream 🙂