Array literals MUST be immutable.

grauzone none at example.net
Fri Feb 19 07:22:15 PST 2010


Steven Schveighoffer wrote:
> On Thu, 18 Feb 2010 20:47:16 -0500, Denis Koroskin <2korden at gmail.com> 
> wrote:
> 
>> On Fri, 19 Feb 2010 00:46:05 +0300, Steven Schveighoffer 
>> <schveiguy at yahoo.com> wrote:
>>> That would be bad,  T[] is implicitly casted from T[N].  Consider 
>>> that you could easily escape stack data using this.  In other words, 
>>> the type system would allow the assignment without the dup.
>>>
>>> -Steve
>>
>> I don't think so. First of all, it is consistent with current behavior:
>>
>> int[] foo()
>> {
>>     int[3] staticArray = [0, 1, 2];
>>     int[] dynamicArray = staticArray;
>>
>>     return dynamicArray;
>> }
> 
> Here is the case I'd say looks bad to me:
> 
> int[] foo()
> {
>    int[] dynamicArray = [0, 1, 2];
>    return dynamicArray;
> }
> 
> If [0, 1, 2] is a static array, then it escapes its scope and corruption 
> ensues.  The implicit static array is the problem, not the assigning of 
> a dynamic array from a static array.  The literal doesn't look like it's 
> a static array.

SafeD will take care of it. As the compiler has to support SafeD anyway, 
the same mechanisms can be used to create warnings or even errors in 
normal D code.

Don wants to make array literals immutable; that means you couldn't just 
assign them to int[] anyway. In both cases, you'd have to use .dup to 
use them as normal, mutable arrays.

Array literals being static arrays would be very handy in other places. 
Wouldn't it be nice if you could just use them for small fixed size 
vectors (wasn't that one of the reasons to make static arrays value 
types)? Then you could write assert([1, 2] + [3, 4] == [4, 6]). No silly 
struct vector "classes" needed.

>> Second, it's very useful to prevent unnecessary heap allocations.
> 
> This is already available by using a static array explicitly.  The 

Static arrays still suck a bit, although making them value types 
improved the situation.

Inside functions, this still allocates an array on the heap and copies 
it into the static array:

int[2] array = [1, 2];

I don't quite know why it can't just behaves as if "array" was declared 
on module level (or as, um, the other "static").

> 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.  From there you can do either a 
> static array if you know it won't escape scope, or a dynamic array (via 
> dup) if you need to modify it and it will escape scope.

How would you "do" a static array from an immutable array?

As I understood, immutable array literals would still require heap 
allocations sometimes. Because even runtime dependent values can be 
immutable.

Actually, if array literals only worked for compile time values, array 
literals could be both immutable and static arrays allocated in the data 
segment.

>>
>> 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

I agree. I wonder how static arrays will be handled in SafeD. Maybe just 
disallow using them as normal arrays? Require an explicit .dup? Anyway, 
it will be safe.

> 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.

Not really an argument, when array literals will be immutable, you could 
as well say:

//the cast is only there to shut up the stupid dmd!
int[] arr = cast(int[])([0, 1, 2]);

> -Steve



More information about the Digitalmars-d mailing list