array cast should be supported corrected

Steven Schveighoffer schveiguy at yahoo.com
Thu Aug 7 08:06:19 PDT 2008


"Robert Fraser" wrote
> Frank Benoit Wrote:
>
>> interface I{}
>> class C : I {}
>>
>> C[] carray = getInstance();
>> I[] iarray = carray; // compile error
>> I[] iarray = cast(I[])carray; // runtime error (1)
>>
>> // correct way:
>> I[] iarray = new I[carray.length];
>> foreach( idx, c; carray ){
>> iarray[idx] = c; // implicit cast
>> }
>>
>> I use a template for doing this, but this looks so ugly.
>> I[] iarray = arraycast!(I)(carray);
>>
>> I think the D compiler should call a runtime method in (1) to do the
>> cast in a loop, instead of doing a simple type change that is not
>> working correctly.
>
>
> The only way to do this is if the cast performed a copy. Consider:
>
> interface I { }
> class A : I { }
> class B : I { }
>
> A[] aarray;
> I[] iarray = aarray;
> iarray ~= new B();
> A a = aarray[0]; // you BROKE my TYPE SYSTEM -- this is an instance of B
>
> When upcasting an array you NEED to copy; you cannot alias. And a cast
> should never make a copy, since that's unexpected behavior.

Aliasing is possible.  The problem is that for interfaces, the pointer is 
changed.  If you change I to be a class, not an interface, then your code 
will compile (of course, it has the same problem as you have added a B to 
the end of an A array, but in general, casting from A[] to B[] where A is 
implicitly castable to B and both A and B use the same amount of space, is 
allowed.  Except for Interfaces :) )

-Steve 





More information about the Digitalmars-d mailing list