Thread overview
Slices and arrays problems?
Jul 01, 2013
Damian
Jul 01, 2013
Ali Çehreli
Jul 01, 2013
Adam D. Ruppe
Jul 01, 2013
Damian
July 01, 2013
void testref(ref int[] arr)
{
    arr[0] = 1;
}

void test(int[] arr)
{
    arr[0] = 1;
}

void main()
{
    //int[] buffer1 = new int[4]; // This works
    int[4] buffer1; // This doesn't
    int[4] buffer2;

    testref(buffer1);
    test(buffer2);
	
    assert(buffer1[0] == 1);
    assert(buffer2[0] == 1);
}

I'm not sure why my code doesn't work?? Isn't the buffer just an array with a fixed length? DMD is telling me 'buffer1 is not an lvalue'. The non ref version works fine?!
July 01, 2013
On 07/01/2013 10:34 AM, Damian wrote:

> void testref(ref int[] arr)
> {
>      arr[0] = 1;
> }
>
> void test(int[] arr)
> {
>      arr[0] = 1;
> }
>
> void main()
> {
>      //int[] buffer1 = new int[4]; // This works
>      int[4] buffer1; // This doesn't
>      int[4] buffer2;
>
>      testref(buffer1);

When that call is made, a slice would have to be created to represent all of the elements of the fixed-length array buffer1. A slice would be needed because buffer1 is not a slice but testref() takes a slice.

By the simplest definition, that slice is an rvalue because it is not defined as a variable in the program.

And rvalues cannot be bound to non-const references. (If I am not mistaken not even to const references yet, if ever.)

>      test(buffer2);

Similarly, when that call is made, a slice is created. The difference is, because the parameter is by-value, the slice gets copied to test(). Now there is no problem because 'arr' is just a local variable of test().

(Note that when I say a slice is created or a slice is copied, they are very cheap operations. A slice is nothing but the number of elements and a pointer to the first one of those elements. Just a size_t and a pointer.)

>
>      assert(buffer1[0] == 1);
>      assert(buffer2[0] == 1);
> }
>
> I'm not sure why my code doesn't work?? Isn't the buffer just an array
> with a fixed length? DMD is telling me 'buffer1 is not an lvalue'. The
> non ref version works fine?!

Ali

July 01, 2013
On Monday, 1 July 2013 at 17:34:39 UTC, Damian wrote:
> Isn't the buffer just an array with a fixed length?

No. A static array is just a block of memory (like in C), whereas a slice is a struct with a length and pointer to a memory block.

A ref slice would write to the length/pointer, which doesn't exist with a static array.

You can get a slice from a static array by putting [] on the end, but to be ref, you'll need a variable with the type "int[]" because then the length and pointers can be changed by the function that accepts it.
July 01, 2013
Thanks Ali and Adam for the good explanations I understand now.