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

Reply via email to