Array literals MUST be immutable.

Denis Koroskin 2korden at gmail.com
Fri Feb 19 07:32:29 PST 2010


On Fri, 19 Feb 2010 17:51:26 +0300, Steven Schveighoffer  
<schveiguy at yahoo.com> wrote:

> The implicit static array is the problem, not the assigning of a dynamic  
> array from a static array.

Not quite true. Here is your example slightly modified:

int[] foo()
{
    int[3] staticArray;
    int[] dynamicArray = staticArray;
    return dynamicArray;
}

It doesn't involve any array literals, but the problem is still there.

> The literal doesn't look like it's a static array.

It really does to me. [a, b, c] is essentially 3 stack pushes and nothing  
else (which is the same as allocating stack space for a static array of 3  
elements).

> This is already available by using a static array explicitly.

How would you initialize such a static array with 3 given elements (a, b  
and c). I certainly wouldn't love verbosity of

int[3] array = void;
array[0] = a;
array[1] = b;
array[2] = c;

> The question is, what should be the default?  I think making it  
> immutable and non-static is the right choice because it can always  
> escape scope, and does not require an allocation.

You can't make [a, b, c] immutable unless all of the a, b and c are  
immutable (or primitive types). For example, what type would that be:

Object a = new Object();
Object b = new Object();
Object c = new Object();

auto array = [a, b, c];

It certainly can't be immutable(Object)[]. I believe it shouldn't be  
Object[] either (you can always make a dynamic array out of static but not  
vice versa). What bonuses would does Object[] provide over Object[3]?  
Object[] doesn't prevent but rather *encourages* escaping reference,  
because D returns static array by values:

// Your preferred way:
Object[] toArray(Object a, Object b, Object c)
{
     return [a, b, c]; // Bug, escaping reference to stack data
}

// My suggestion
Object[3] toArray(Object a, Object b, Object c)
{
     return [a, b, c]; // Correct
}

>>
>> I would prefer static arrays not to cast to dynamic ones implicitly,  
>> but using opSlice syntax instead:
>>
>> int[] arr = [0, 1, 2]; // error
>> int[] arr = [0, 1, 2][]; // fine, use on your own risk
>
> This is just an annoyance error.  What will happen is people will  
> constantly just use the brackets to shut up the compiler without  
> thinking about what it really means.
>

<sarcasm>Sure, just hide the bug without compiler worrying you about  
presence of one. </sarcasm>

You suggestion encourages unsafe by default, which is bad bad bad. It just  
shouldn't compile. People should just use .dup if they need a dynamic  
array unless they *really* know what they are doing, and use []. It should  
never happen in SafeD, and probably not even allowed.



More information about the Digitalmars-d mailing list