Steven Schveighoffer wrote:
On Fri, 09 Oct 2009 06:11:50 -0400, grauzone <[email protected]> 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
I don't understand why runtime-determined array literals even exist.
They're not literals!!!
They cause no end of trouble. IMHO we'd be *much* better off without them.