On Fri, 12 Feb 2016 14:32:32 -0500, Steven Schveighoffer wrote:

> what I'm trying to say safe shouldn't allow is reinterpret casting.
> i.e.: *cast(T*)(&x)
> 
> So casting IMO shouldn't be allowed unless it invokes some kind of
> handler that ensures the conversion is safe.
> 
> I'd include in this list:
> 
> a) casting between object types
> b) casting builtin types that are not,
> or do not contain, references (that are defined by the compiler)
> c) casting an aggregate that has a matching opCast

Casting an array is basically a backdoor way to make a union, ignoring 
opCast. One of the cases that should be explicitly disallowed here (and 
of course it isn't). Observe:

import std.stdio;
struct A {
        void* m;
        size_t i;
}
struct B {
        size_t i;
        A opCast() {
                return A(null, i);
        }
}

void main() @safe {
        A[] aa = [A(new int, 5)];
        auto bb = cast(B[])aa;
        writeln(bb[0].i);  // prints -22192128
}

If this honored opCast, it would print 5. Instead it prints a pointer 
address. (Also, the length of array bb is 2.)

This corresponds to what the spec says, but that's probably not the 
desired behavior.

Reply via email to