When is array-to-array cast legal, and what does actually happen?

Lars T. Kyllingstad public at kyllingen.NOSPAMnet
Tue Feb 23 00:10:21 PST 2010


Daniel Keep wrote:
>> ...
>>
>> I see that neither the constructor nor the postblit is called.
>> Apparently the bit representation is used. This has the risk of
>> violating struct invariants.
>>
>> Is it legal?
>>
>> Thank you,
>> Ali
> 
> cast is to value conversions what a tactical nuclear strike is to
> peaceful negotiations.  cast is specifically *designed* to circumvent
> the type system's protections [1].
> 
> If you want to do a value conversion, *do a value conversion*.  Allocate
> a new array and convert each member.  cast doesn't call the constructor
> or the postblit because it's doing a pointer conversion.
> 
> Your code is basically equivalent to this:
> 
> void main()
> {
>     auto tmp = "hello"d;
>     auto mine = cast(MyChar*)(tmp.ptr)
>         [0..(tmp.length*typeof(tmp[0]).sizeof)/MyChar.sizeof)];
> }
> 
> That is, it's doing an unsafe, unchecked pointer cast, then re-slicing
> the array.

There is another gotcha to watch out for:  Array literals are treated 
differently from other arrays.  That is, the compiler does a value 
conversion for literals.


import std.stdio;

void main()
{
     auto a = [1, 2, 3];
     auto b = cast(float[]) a;
     auto c = cast(float[]) [1, 2, 3];

     writeln(a);   // Prints "1 2 3"
     writeln(b);   // Prints "1.4013e-45 2.8026e-45 4.2039e-45"
     writeln(c);   // Prints "1 2 3"
}

-Lars


More information about the Digitalmars-d-learn mailing list