T[new]

Steven Schveighoffer schveiguy at yahoo.com
Mon Aug 10 12:06:15 PDT 2009


On Mon, 10 Aug 2009 14:38:24 -0400, Stewart Gordon <smjg_1998 at yahoo.com>  
wrote:

> Since nobody's yet asked....
>
> What type would .dup and .idup return?
>
> The best choice I can see is to make .dup return T[new] and .idup return  
> invariant(T)[].

This brings up another question.  Should something like immutable(T)[new]  
or const(T)[new] be even valid?  Consider this:

immutable(char)[new] str = "hello".idup; // not sure how you convert a  
literal to an array, but assume it works for now.

assert(str.capacity == 16); // assume GC still allocates 16 minimum blocks
str ~= " there";

auto slice = str[5..$];

str.length = 5;

str ~= " world";

assert(slice == " there"); // fails?

We most likely have the same issue here with immutable data as we do  
today, just not as obvious.  Although it's a corner case, it does violate  
immutability without casts.

There are several options:

1. immutable(T)[new] and const(T)[new] are invalid.  This limits us more  
than the current regime, but is a questionable construct to begin with,  
considering it allows appending in place (you can always create a new  
array with concatenation).
2. immutable(T)[new] and const(T)[new] are equivalent to immutable(T[new])  
and const(T[new]) respectively.  This simplifies generic programming and  
still prevents abuses.
3. when you shrink an array of immutable/const elements' length, the  
capacity automatically shrinks to prevent overwriting previous data.  This  
still leaves mutable data with the overwrite problem, but it doesn't  
violate const.
4. same as #3 but do it for both immutable or mutable arrays.

Also, implicit casting to const needs to be addressed, normally you can't  
do this with templated types (if that's how the underlying type is  
implemented).

-Steve



More information about the Digitalmars-d mailing list