-----
void main() @safe {
Object[] objs = [ new Object() ];
void[] arr1 = objs;
void[] arr2 = [ 123, 345, 567 ];
arr1[] = arr2[]; // overwrites pointers with arbitrary ints
}
-----
It should be illegal to copy the contents of one void[] to another void[], since void[] by definition is a type-erased array and can represent any arbitrary type, including types with indirections. Since type information has been erased, there is no way to verify that the destination array has no indirections, so to guarantee @safety, such an operation must not be allowed in @safe code.
Comment #1 by nick — 2016-06-13T21:22:03Z
Shouldn't we just disallow all writes to a void[] in safe code?
Comment #2 by hsteoh — 2016-06-14T15:15:55Z
It's not just writing to void[] that's the problem. Consider:
----
int[] intArr = [ 1,2,3,4,5 ];
void[] voidArr = intArr; // OK, every array converts to void[]
int*[] ptrArr;
ptrArr.length = 5;
ptrArr[] = voidArr[]; // reinterpret intArr as pointers
ptrArr[0] = 1; // oops
----
Basically, *anything* that leads to reinterpretation of something as pointer values cannot be allowed in @safe.
Comment #3 by schveiguy — 2016-06-14T15:26:44Z
(In reply to hsteoh from comment #2)
> It's not just writing to void[] that's the problem. Consider:
>
> ----
> int[] intArr = [ 1,2,3,4,5 ];
> void[] voidArr = intArr; // OK, every array converts to void[]
> int*[] ptrArr;
> ptrArr.length = 5;
> ptrArr[] = voidArr[]; // reinterpret intArr as pointers
Wait, does this really work (I didn't think it did)? If so, isn't it still implicitly doing this:
(cast(void[])ptrArr)[] = voidArr[];
Which is still writing void data.
Comment #4 by hsteoh — 2016-06-14T15:40:34Z
Oh, you're right, it doesn't compile because implicit conversion from void[] to int*[] is not allowed. OK, nevermind what I said, then. :-D