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.