Thread overview
Cannot copy void[] to void[] in @safe code?
Jul 08
wjoe
Jul 08
ag0aep6g
Jul 08
wjoe
July 08

Why is that ?
My understanding is that a void[] doesn't have a distinct type but since the length is bytes and not elements this makes me believe that under the hood they are byte arrays - or, rather, managed chunks of memory.
How's copying memory without a distinct type different from copying, say, an ubyte[] to an ubyte[] ?

The compiler doesn't complain about that in @safe code:

@safe void copy_voidA_to_ubyteA(in void[] s) {
  ubyte[] d;
  d.length = s.length;
  d[0..$] = cast(const ubyte[])s[0..$];
}
copy_voidA_to_ubyteA([1,2,3,4]);

But what if I copy pointers into an ubyte[] ?
void[] are scanned by the GC but ubyte[] aren't.

July 08

On Friday, 8 July 2022 at 10:58:24 UTC, wjoe wrote:

>

My understanding is that a void[] doesn't have a distinct type but since the length is bytes and not elements this makes me believe that under the hood they are byte arrays - or, rather, managed chunks of memory.
How's copying memory without a distinct type different from copying, say, an ubyte[] to an ubyte[] ?

You're allowed to copy from ubyte[] to ubyte[]. But you're not allowed to copy from ubyte[] to int*[], because reinterpreting a bunch of bytes as pointers is not safe.

The thing about void[] is that it can point to memory that also has a typed alias. You can have a void[] and a ubyte[] pointing to the same memory. And you can have a void[] and an int*[] pointing to the same memory. So if you were allowed to copy from void[] to void[], you'd practically be allowed to copy from ubyte[] to int*[]. But that's not safe.

In code:

void main() @safe
{
    ubyte[] some_bytes = [1, 2, 3, 4, 5, 6, 7, 8];
    int*[] some_pointers = [new int];
    void[] v1 = some_bytes;
    void[] v2 = some_pointers;
    v2[] = v1[]; /* creating invalid pointers */
    int x = *some_pointers[0]; /* undefined behavior */
}
July 08

On Friday, 8 July 2022 at 12:26:03 UTC, ag0aep6g wrote:

>

You're allowed to copy from ubyte[] to ubyte[]. But you're not allowed to copy from ubyte[] to int*[], because reinterpreting a bunch of bytes as pointers is not safe.

The thing about void[] is that it can point to memory that also has a typed alias. You can have a void[] and a ubyte[] pointing to the same memory. And you can have a void[] and an int*[] pointing to the same memory. So if you were allowed to copy from void[] to void[], you'd practically be allowed to copy from ubyte[] to int*[]. But that's not safe.

That makes a lot of sense. Thanks!