Array literals' default type

Steven Schveighoffer schveiguy at yahoo.com
Fri Oct 9 05:04:16 PDT 2009


On Fri, 09 Oct 2009 06:11:50 -0400, grauzone <none at example.net> wrote:

> Steven Schveighoffer wrote:
>> immutable(double)[] - The compiler stores a copy of this array  
>> somewhere in ROM and initializes the stack variable with the immutable  
>> pointer to the data.
>
>
> And what about
>
> void foo(int x) {
>     auto a = [1, x, 2];
>
> ?
>
> Should it create an immutable array on the heap? And if the user happens  
> to need a mutable one, he has to dup it? (Causing one unnecessary memory  
> allocation.)

This is an interesting question.  This literal obviously cannot be  
ROM-allocated, so it must be heap allocated.  But do we want heap  
allocated literals forced into being immutable?

I think array literals need to go through a major overhaul.  The type of  
the literal is highly dependent on both how you want to use it, and the  
values given to it.  Similar to how a 1 can be interpreted as a byte,  
maybe an array literal needs to generate different code depending on how  
you assign it.

Here's a stab at some rules I'd like to see implemented (when I say  
assigned to variable, I mean assigned, or casted, or passed as argument,  
etc):

1. If an array literal is assigned to a variable of type immutable(T)[] or  
const(T)[]:
    a. If any of the elements of the array are runtime-decided, then the  
array is allocated on the heap.
    b. Otherwise, the array is set in ROM, and an alias to the array is  
returned.
2. If an array literal is assigned to a variable of type T[] where T is  
not immutable or const, it is *always* allocated on the heap.
3. If an array literal is assigned to a variable of type T[], and all of  
the elements can be either interpreted as type T or implicitly casted to  
type T, the literal shall be interpreted as if it were written [cast(T)e1,  
cast(T)e2, ...]
4. If an array literal is assigned to a variable with the auto specifier,  
the type is immutable(T) where T is the most basic type that all the  
elements can be interpreted as.  Then rule 1 is followed.
5. If an array literal is assigned to a variable that is a static array,  
no heap allocation shall occur.
6. If an array literal is .dup'd, it will be treated as if it were  
assigned to a T[] where T is mutable.  If it's assigned to an auto, then T  
is the most basic type that all elements can be interpreted as.
7. If an array literal is .idup'd, it will be treated as if it were  
assigned to an immutable(T)[].  If it's assigned to an auto, then T is the  
most basic type that all elements can be interpreted as.

I suck at writing rules :)  Here are some examples of what I think should  
happen, and the types interpreted:

int[] x = [1,2,3]; // type: int[], on heap.
auto x = [1,2,3]; // type: immutable(int)[], ROM.

int y = 2;

auto x = [1,y,3]; // type: immutable(int)[], heap.
int[] x = [1,y,3]; // type: int[], heap.

auto x = [1,y,3].dup; // type int[], heap, only one allocation.
auto x = [1,2,3].dup; // type: int[], heap, only one allocation.

auto x = [1,y,3].idup; // type: immutable(int)[], heap, only one  
allocation.
auto x = [1,2,3].idup; // type: immutable(int)[], ROM.

auto x = [1,2.2,3]; // type: immutable(double)[], ROM.
immutable(double) x = [1,2,3]; // type: immutable(double)[], ROM.

int[3] x = [1,2,3]; // type int[3u], on stack, no heap allocation.

auto x = "hello"; // type immutable(char)[], ROM.
char[] x = "hello"; // type char[], on heap.

This is all principal of least surprise.  Do people think this is a good  
idea?

> (Wait, is .dup even enough to get a mutable array, or will it return  
> just another immutable one?)

.dup always returns a mutable array, regardless of the immutability of the  
source.  .idup returns an array of immutable data.

> int[3] a = [1, x, 2];
>
> Ideally, the line of code above would not cause a heap allocation.

I agree.  Automatic heap allocations for array literals that don't need to  
be heap allocated is crappy.

-Steve



More information about the Digitalmars-d mailing list