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