Assigning a static array

Steven Schveighoffer schveiguy at yahoo.com
Thu Apr 18 14:54:06 PDT 2013


> There is a similar problem with the automatically generated array  
> arguments.
>
> The following constructor takes any number of ints that come in array  
> form:
>
> import std.stdio;
>
> struct S
> {
>      int[] a;
>
>      this(int[] args...)
>      {
>          a = args;
>      }
>
>      void foo()
>      {
>          writeln(a);
>      }
> }
>
> void main()
> {
>      S[] a;
>
>      foreach (i; 0 .. 2) {
>          a ~= S(i, i, i);  // <-- WARNING temporary array
>      }
>
>      foreach (e; a) {
>          e.foo();
>      }
> }
>
> The program prints the following because the temporary arrays that are  
> generated when calling the constructors are long gone:
>
> [1, 1, 1]
> [1, 1, 1]
>
> The programmer *may have* ;) expected the following output:
>
> [1, 1, 1]
> [2, 2, 2]

There is no guarantee that the incoming array from a variadic function is  
heap-based.

But an interesting way to deal with it is that you can overload with an  
explicit slice parameter, and the variadic version will ONLY bind to a  
variadic call.

For example, in dcollections' ArrayList I have two constructors:

    /**
      * Create an array list based on a number of elements.
      */
     this(V[] elems...)
     {
         _array = elems.dup;
     }

     /**
      * Use an array as the backing storage.  This does not duplicate the
      * array.  Use new ArrayList(storage.dup) to make a distinct copy.   
Beware
      * of using a stack-based array when using this constructor!
      */
     this(V[] storage)
     {
         _array = storage;
     }

The first version binds only to cases where the parameter is not  
*explicitly* a slice, so I am guaranteed that the array is allocated on  
the stack!  The second binds to slices, and I assume from my comment,  
fixed-sized arrays (been a while since I looked at that code).

And the correct expectation for your code should be:

[0, 0, 0]
[1, 1, 1]

:)

-Steve


More information about the Digitalmars-d-learn mailing list