Is this a desing rationale? (static array object member)

Steven Schveighoffer schveiguy at yahoo.com
Mon Oct 1 07:28:33 PDT 2007


"Brian Hsu" <brianhsu.hsu at gmail.com> wrote in message 
news:fdkvv1$2a8q$1 at digitalmars.com...
> Finally, is this behavior reasonable? Since I didn't declare that int [] 
> as a static class member, even though they have same initialization array 
> literal, but I would expect that a.z/b.z they should be different array 
> have same content. (As in Java or C++)

If you examine the difference between this and the Java syntax, there lies 
your problem:

class Test
{
   int[] z = new int[] {1,1,1,1,1};
   ...
}

notice the new keyword.  This means you are making a new array.

In your example, you are not making a new array, you are setting a pointer 
to an existing array.

In java, it is more akin to this:

class Test
{
   static int[] _z = new int[] {1,1,1,1,1};
   int[] z = _z;
}

(BTW, haven't done java coding in a while, this might be syntactically 
wrong)

In java, to get the behavior you want, you have to declare a new array.  The 
same is for D.  The only issue is that default initializers outside 
constructers are evaluated at compile-time.  So to get the equivalent, you 
must do this:

class Test
{
   int[] z;
   Test()
   {
       z = ([1,1,1,1,1]).dup;
   }
}

Note also that you are using a dynamic array.  If you wanted to use a static 
array (one whose length is constant), this works as it copies the contents 
from the other array.

class Test
{
   int[5] z = [1,1,1,1,1];
}

BTW, I agree with Janice's and other's suggestions that array literals 
should be constant.  Because this example is even more disturbing:

import tango.io.Stdout;

class Test
{
  int[] z = [1,1,1,1,1];
  void addOne()
  {
    for(int i = 0; i < z.length; i++)
    {
      z[i]++;
    }
  }
}

int main(char[][] args)
{
  Test a = new Test;
  a.addOne();
  Test b = new Test;

  // outputs 22222
  foreach(int x; b.z)
  {
    Stdout(x);
  }
  Stdout.newline();
  return 0;
}

I can see bugs creeping in too.  Imagine if you originally coded this exact 
example with the following declaration of z:

int[5] z = [1,1,1,1,1];

Then later on you decide it is better to have z be a dynamic array.  There 
are no compiler warnings/errors!  By just removing the 5, I've introduced a 
super-subtle far-reaching bug.

-Steve 





More information about the Digitalmars-d mailing list