Island/Windows, C# wrong syntax on array assignment

@ck @mh

I believe the following C# code has valid syntax, but Island/C# compiler gives me the following errors:

error E415: Multi-dimensional array with open high bounds not supported on this platform
error E129: Cannot cast from “Int32[0…1, 0…2]” to "Int32[0…, 0…]"

     public Int32 Main(string[] args)
     {
         int[,] data = new int[2, 3] {{1, 2, 3},{4, 5, 6}};
         writeLn($"{data[1,2]}");
     }

ConsoleApplication1.7z (4.4 KB)

It’s a tricky one. We don’t have a syntax for static arrays in C#, because we couldn’t find anything that “fits”, syntax wise. However: if you use var on the left side it does work.

You meant - we don’t have a syntax for static arrays in C# on Island platform?

The code works on .NET

Indeed we do not. The difference on .NET is that it’s a dynamic array there.

I am still confused -
Then using C#/Island, how can I initialize a dynamic array like
Int[,] = new ?

At the moment you can’t yet (in C# mode); I’m working on thinking up a syntax for static multidim arrays.

A temporary workaround is to define an alias in Pascal:

type MyArray = array[0…5, 0…6] of Integer;
and use MyArray on the C# side.

Thank you - but this is static array with predetermined high bound.

What I am confused is : how to initialize dynamic array int [, ]

I guess right now on C#/Island, multidimensional array like int[,] is not supported yet, right?

We don’t allow dynamic multidim arrays (ie without a predefined bound) on Island/Java/Toffee currently now. It’s a lot of work to implement, and every access needs special bounds checking and math for index access to implement, so we (currently) don’t do it.

@ck
I followed your advice. But I found:

  • var data = int[2, 3]
    Internally, data is treated by the compiler as array of array of integer, i.e., jagged array int[][], with dimension 2, and 3, for the first level, and second level respectively

The memory region is two seperate parts: int[0][], and int[1][]

  • var data = new int[2, 3] {{0,0,0},{0,0,0}}
    Internally, data is treated by compiler as retangular array int[2,3], with all values initialized to 0
    The memory region is one continuous part.

I think this is not consistent with C# array specification., especially the difference between rectangular array vs. jagged array.

I think it makes more sense to differentiate rectangular array vs jagged array explicitly, and consistent with C# spec:

  • var data = new int[2,3]
    should be treated as rectangular array of continuous memory region (0…5), and if no explicit initializer provides, elements should be set to default value, i.e., 0
  • var data = new int[2][3]
    should be treated as jagged array of TWO seperate memory region int[0][], and int[1][]

This distinction would help to apply memcpy for copying data correctly….

I think I have it.

		public static void Main()
		{
		  int[..15, ..13] c;
		  int[..2, ..2] d = {{0,1}, {1,2}};
		  c[0,1] = 15;
		}

The first creates an array with 15 * 13 elements (0…14, 0…12), the second 2*2 (0…1, 0…1). Both will be value types on Island/Toffee. (Next builds, not withstanding any bugs)

1 Like

What about the following cases:

Var A = new int[12,15];
Var B = new int[12][15]

Is A dynamic array with continuous memory region of size 12x15?
Is B dynamic array of 12 independently-allocated memory regions, each of size 15?
@ck

Both are dynamic.

you want this for static:

Var A = new int[..12,..15];

the above are all existing syntaxes for dynamic arrays.

1 Like

I downloaded the latest build, but it still seems to have some “inconsistencies”:

From the sample code (in the Figure below, and attached), I had expected:

  • var a = new int[2, 3] and var b = new int[2, 3] {{0,1,2},{3,4,5}} both should have exactly the SAME type of memory allocation.

But it seems to me:

  • var a = new int[2, 3] is treated as int[2] [ ], with int[0] [ ] and int[1] [ ] memory allocated in two separate chunks .
  • var a = new int[2, 3] {{0,1,2},{3,4,5}} is treated as int[2, 3], with memory allocated in one continuous chunk;

My assumption is that — they should have the same style of memory allocation, regardless whether an initializer is provided or not, because both are declared as int[2, 3], NOT int[ ] [ ]

Can you please clarify? Or my assumption is completely off tangent?

@ck

ConsoleApplication1.7z (4.9 KB)

Oke so the issue is this:

  • var a = new int[2, 3] is treated as int[2] [ ], with int[0] [ ] and int[1] [ ] memory allocated in two separate chunks .
  • var a = new int[2, 3] {{0,1,2},{3,4,5}} is treated as int[2, 3], with memory allocated in one continuous chunk;

both of these are dynamic arrays and the compiler will do it’s best to well, make them work. What you want to do instead is this:

  • var a = new int[…2, …3] is treated as int[2] [ ], with int[0] [ ] and int[1] [ ] memory allocated in two separate chunks .
  • var a = new int[…2, …3] {{0,1,2},{3,4,5}} is treated as int[2, 3], with memory allocated in one continuous chunk;

The only reason it makes it into a dynamic array is to make code from .NET compile properly in Java.

If I understand correctly - do you mean that
Whether the memory is allocated in one continuous chunk, or two separate chunk, must be determined by the existence of the initializer?

And the reason to do so, is for the purpose of making Java to work properly?

new int[…2,…3]
vs
new int[…2,…3] {{1,2,3},{4,5,6}}

They cannot BOTH have one continue chunk of memory? I am still confused by what you said. I just want to make sure they have the SAME (consistent) memory treatment.

so the …2,…3 syntax always generates 1 block.

On Java/Toffee/Island, new int[2, 3] will generate a new int[2][3] (also as designed)

The only weird thing is that new int[2,3]{…} doesn’t. I’ll take a look at that.

1 Like