Thread overview
AA of AAs -- ArrayBoundsError
Oct 29, 2007
nobody
Oct 29, 2007
Matti Niemenmaa
Oct 29, 2007
nobody
Oct 29, 2007
Matti Niemenmaa
October 29, 2007
The following code results in an ArrayBoundsError with my v1.015 compiler:

  typedef size_t IA;
  typedef size_t IB;
  typedef uint V;

  void main(char[][] args)
  {
    V[IB] [IA] test;
    test[cast(IA) test.length]
      [cast(IB) test[cast(IA) test.length].length] =
    cast(V) (test.length * test[cast(IA) test.length].length);
  }
October 29, 2007
nobody wrote:
> The following code results in an ArrayBoundsError with my v1.015 compiler:
> 
>   typedef size_t IA;
>   typedef size_t IB;
>   typedef uint V;
> 
>   void main(char[][] args)
>   {
>     V[IB] [IA] test;
>     test[cast(IA) test.length]
>       [cast(IB) test[cast(IA) test.length].length] =
>     cast(V) (test.length * test[cast(IA) test.length].length);
>   }

The problem is on the right hand side of the assignment, namely on the access test[cast(IA) test.length]. The AA test is empty, so retrieving any element will fail with an ArrayBoundsError.

Assign test[1][1] = something; first, and then it will work. (1, because test.length will be 1 after the assignment.)

-- 
E-mail address: matti.niemenmaa+news, domain is iki (DOT) fi
October 29, 2007
Matti Niemenmaa wrote:
> nobody wrote:
>> The following code results in an ArrayBoundsError with my v1.015 compiler:
>>
>>   typedef size_t IA;
>>   typedef size_t IB;
>>   typedef uint V;
>>
>>   void main(char[][] args)
>>   {
>>     V[IB] [IA] test;
>>     test[cast(IA) test.length]
>>       [cast(IB) test[cast(IA) test.length].length] =
>>     cast(V) (test.length * test[cast(IA) test.length].length);
>>   }
> 
> The problem is on the right hand side of the assignment, namely on the access
> test[cast(IA) test.length]. The AA test is empty, so retrieving any element will
> fail with an ArrayBoundsError.
> 
> Assign test[1][1] = something; first, and then it will work. (1, because
> test.length will be 1 after the assignment.)
> 

I really messed up the example. You are correct that my example should not work. However, both the following add functions fail when I think they shouldn't:

  import std.stdio;


  typedef size_t I;
  struct Si { uint val; }
  struct Sa
  {
    Si[I][I] table;

    void add(I i, Si si)
    {
      table[i][cast(I) table[i].length] =  si;
    }
  }

  struct Sb
  {
    Si[][I] table;

    void add(I i, Si si)
    {
      if(table[i] is null)
        table[i] = new Si[0];

      table[i].length = table[i].length + 1;
      table[i][table[i].length - 1] = si;

    }
  }

  void main(char[][] args)
  {
    Si si;
    Sa sa;
    try
    {
      sa.add(cast(I) 17, si);
    } catch(Error e)
    {
      writef("Sa failed\n");
    }

    Sb sb;
    try
    {
      sb.add(cast(I) 17, si);
    } catch(Error e)
    {
      writef("Sb failed\n");
    }
  }
----------------------------------------------------------------
Sa failed
SB failed
October 29, 2007
nobody wrote:
> Matti Niemenmaa wrote:
>> nobody wrote:
>>> The following code results in an ArrayBoundsError with my v1.015 compiler:
>>>
>>>   typedef size_t IA;
>>>   typedef size_t IB;
>>>   typedef uint V;
>>>
>>>   void main(char[][] args)
>>>   {
>>>     V[IB] [IA] test;
>>>     test[cast(IA) test.length]
>>>       [cast(IB) test[cast(IA) test.length].length] =
>>>     cast(V) (test.length * test[cast(IA) test.length].length);
>>>   }
>>
>> The problem is on the right hand side of the assignment, namely on the
>> access
>> test[cast(IA) test.length]. The AA test is empty, so retrieving any
>> element will
>> fail with an ArrayBoundsError.
>>
>> Assign test[1][1] = something; first, and then it will work. (1, because test.length will be 1 after the assignment.)
>>
> 
> I really messed up the example. You are correct that my example should not work. However, both the following add functions fail when I think they shouldn't:
> 
>   import std.stdio;
> 
> 
>   typedef size_t I;
>   struct Si { uint val; }
>   struct Sa
>   {
>     Si[I][I] table;
> 
>     void add(I i, Si si)
>     {
>       table[i][cast(I) table[i].length] =  si;
>     }
>   }

This is essentially the same case as your original example. table[i].length results in an error because table[i] does not exist yet.

>   struct Sb
>   {
>     Si[][I] table;
> 
>     void add(I i, Si si)
>     {
>       if(table[i] is null)
>         table[i] = new Si[0];
> 
>       table[i].length = table[i].length + 1;
>       table[i][table[i].length - 1] = si;
> 
>     }
>   }

As above, "if (table[i] is null)" results in an error because table[i] does not
exist yet. What would, however, work is "if (!(i in table))". (You might have
noticed this if you would have output the error instead of just "Sb failed": the
ArrayBoundsError is on the line where the if statement is.)

BTW, you should post these on the digitalmars.D.learn newsgroup unless you're 100% sure they're bugs.

-- 
E-mail address: matti.niemenmaa+news, domain is iki (DOT) fi