www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - How to initialize static arrays with variable data

reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
In another thread, Don (and others including myself) advocate that an  
array literal should be an immutable array.  This has benefits when you  
want to use immutable arrays that have statically determined values.  It  
means you don't require heap allocations when assigning an immutable  
array, just like strings are handled.

The point was brought up by Walter (and previously by others), "what about  
initializing non-immutable arrays with runtime-determined data?"

i.e.

int[] x = [a, b, c];

The answer is simply, use a library function to allocate the array on the  
heap.

i.e.

int[] x = toArray(a, b, c);

This works great, but there is still one missing piece that was pointed  
out by Denis Koroshin and grauzone.  What about static arrays that you  
*don't* want to initialize on the heap?

i.e.

int[3] x = [a, b, c];

Currently, the act of making an array literal allocates on the heap.  If  
array literals become immutable, then you can't do [a, b, c] because it is  
determined at runtime.  So how can this be made to work?  Should it be a  
library function?

i.e.

int[3] x = toStatic(a, b, c);

Or should the compiler do something magic, such as type array literals  
with runtime values in them as a static array?  It would be nice to allow  
this:

int[3] x = [a, b, c];

but then to be safe (so you cannot easily construct an escaping array) you  
cannot allow this:

int[] x = [a, b, c];

Any other ideas?  I think this problem really needs a solution if we are  
going to address array literals.

-Steve
Feb 19 2010
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Steven Schveighoffer:

 It would be nice to allow this:
 int[3] x = [a, b, c];

This is allowed now. Regarding dynamic arrays allocated on the stack I can see few possibilities: 1) Make the compiler smarter so it can perform escape analysis on arrays too, and not just on objects. 2) Use a specified syntax, time ago I have proposed a natural one: scope int[] arr = new int[n]; I like this, but I think Walter plans to remove scoped classes too, so I think he doesn't love the idea of scoped dynamic arrays. 3) Allow variable length stack allocated arrays, like in C99, you can use the natural syntax: int[n] arr; Where n can also be a compile time variable. I like this, I think Andrei likes it enough, but I think Walter is not interested. The risk with such arrays is of a stack overflow. Bye, bearophile
Feb 19 2010
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 19 Feb 2010 12:15:20 -0500, bearophile <bearophileHUGS lycos.com>  
wrote:

 Steven Schveighoffer:

 It would be nice to allow this:
 int[3] x = [a, b, c];

This is allowed now.

Yes, but 1) it allocates the literal on the heap and then throws it away, and 2) it would not be allowed if array literals are only allowed to be immutable. I'm speaking from the context assuming that array literals are made to be immutable by default. -Steve
Feb 19 2010
prev sibling next sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Fri, 19 Feb 2010 20:28:20 +0300, Steven Schveighoffer
<schveiguy yahoo.com> wrote:

 On Fri, 19 Feb 2010 12:15:20 -0500, bearophile  
 <bearophileHUGS lycos.com> wrote:

 Steven Schveighoffer:

 It would be nice to allow this:
 int[3] x = [a, b, c];

This is allowed now.

Yes, but 1) it allocates the literal on the heap and then throws it away, and 2) it would not be allowed if array literals are only allowed to be immutable. I'm speaking from the context assuming that array literals are made to be immutable by default. -Steve

It just *can't* be immutable unless all the variables involved are implicitly castable to immutable. And what if I need a *mutable* array? .dup it? My suggestion would be to be consistent with built-in types. See the following examples: auto x1 = 1; // defaults to int, not immutable int immutable auto x2 = 1; // but immutable also fine // typeof(x2) = immutable(int) int a = 42; immutable auto x3 = a; // you can also construct immutable from a mutable // variable, if it is implicitly castable to one Similarly: auto x1 = [1]; // int[1] immutable auto x2 = [1]; // immutable(int)[1] int a = 42; immutable auto x3 = [a]; // immutable(int)[1]
Feb 19 2010
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 19 Feb 2010 12:53:56 -0500, Denis Koroskin <2korden gmail.com>  
wrote:

 On Fri, 19 Feb 2010 20:28:20 +0300, Steven Schveighoffer
 <schveiguy yahoo.com> wrote:

 On Fri, 19 Feb 2010 12:15:20 -0500, bearophile  
 <bearophileHUGS lycos.com> wrote:

 Steven Schveighoffer:

 It would be nice to allow this:
 int[3] x = [a, b, c];

This is allowed now.

Yes, but 1) it allocates the literal on the heap and then throws it away, and 2) it would not be allowed if array literals are only allowed to be immutable. I'm speaking from the context assuming that array literals are made to be immutable by default.

implicitly castable to immutable.

In the case of [a, b, c], it either doesn't compile, or is not an immutable array. Because a, b, and c are runtime values (and potentially different for every usage of that expression), it makes no sense to make them immutable. In the case of [1, 2, 3], all the items are available at compile-time, and an immutable array can be created.
 And what if I need a *mutable* array? .dup it?

Or use a library function that creates a new array from runtime-determined elements. But this problem is already solved, we are talking about static arrays, not dynamic arrays.
 My suggestion would be to be consistent with built-in types.

That's fine for static arrays, but the crux of the matter is the syntax. Dynamic arrays are inherently reference types. You cannot simply convert them to and from mutable and immutable. So you either can't have the same syntax to initialize dynamic arrays as you have to initialize static arrays, or the compiler has to treat the literals for arrays differently depending on usage. There is not one type that an array literal can be that translates correctly to dynamic, dynamic immutable, and static arrays. So the compiler could do some magic to make the type special, but it also has to behave differently for different uses. It's a complicated problem to solve, and the question is, where does the solution belong, in the library or the compiler? -Steve
Feb 19 2010
prev sibling next sibling parent KennyTM~ <kennytm gmail.com> writes:
On Feb 20, 10 00:47, Steven Schveighoffer wrote:
 In another thread, Don (and others including myself) advocate that an
 array literal should be an immutable array. This has benefits when you
 want to use immutable arrays that have statically determined values. It
 means you don't require heap allocations when assigning an immutable
 array, just like strings are handled.

 The point was brought up by Walter (and previously by others), "what
 about initializing non-immutable arrays with runtime-determined data?"

 i.e.

 int[] x = [a, b, c];

 The answer is simply, use a library function to allocate the array on
 the heap.

 i.e.

 int[] x = toArray(a, b, c);

 This works great, but there is still one missing piece that was pointed
 out by Denis Koroshin and grauzone. What about static arrays that you
 *don't* want to initialize on the heap?

 i.e.

 int[3] x = [a, b, c];

 Currently, the act of making an array literal allocates on the heap. If
 array literals become immutable, then you can't do [a, b, c] because it
 is determined at runtime. So how can this be made to work? Should it be
 a library function?

 i.e.

 int[3] x = toStatic(a, b, c);

 Or should the compiler do something magic, such as type array literals
 with runtime values in them as a static array? It would be nice to allow
 this:

 int[3] x = [a, b, c];

 but then to be safe (so you cannot easily construct an escaping array)
 you cannot allow this:

 int[] x = [a, b, c];

 Any other ideas? I think this problem really needs a solution if we are
 going to address array literals.

 -Steve

Why can't [a,b,c] be made into toArray(a,b,c).idup?
Feb 19 2010
prev sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Fri, 19 Feb 2010 23:12:02 +0300, KennyTM~ <kennytm gmail.com> wrote:

 Why can't [a,b,c] be made into toArray(a,b,c).idup?

Because the goal is to prevent unnecessary heap allocations.
Feb 19 2010