Thread overview
void[] vs ubyte[] - differences?
Jul 16
z
Jul 17
Dukc
July 16
import std;

void main()
{
    void[] a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 0x12345678];
    void[] b = cast(ubyte[])[0, 1, 2, 3, 4, 5, 6, 7, 8];
    ubyte[] c = cast(ubyte[])(cast(void[])[0, 1, 2, 3, 4, 5, 6, 7, 8,0x12345678]);
    ubyte[] d = [0, 1, 2, 3, 4, 5, 6, 7, 8];
    void[] e = cast(ubyte[])a;// same result as a
    void[] f = cast(void[]) a;// same result as a
    writeln(a);
    writeln(b);
    writeln(c);
    writeln(d);
    writeln(e);
    writeln(f);
    writeln(void.sizeof);
}

[0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 120, 86, 52, 18]
[0, 1, 2, 3, 4, 5, 6, 7, 8]
[0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 120, 86, 52, 18]
[0, 1, 2, 3, 4, 5, 6, 7, 8]
[0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 120, 86, 52, 18]
[0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 120, 86, 52, 18]
1
//it also appears to expose the platform's endianness

I also see this in the language documentation :

A void array cannot be indexed.

But i can slice it just fine in DMD 2.111...
Is this by design or is there a hole in the language specification? By extension what the differences between void, ubyte, void[], ubyte[] really? The language documentation doesn't appear to be explaining everything.
Thanks in advance

July 16
On Wed, Jul 16, 2025 at 01:29:01PM +0000, z via Digitalmars-d-learn wrote: [...]
> I also see this in the language documentation :
> ```
> A void array cannot be indexed.
> ```
> But i can slice it just fine in DMD 2.111...

Probably an oversight.


> Is this by design or is there a hole in the language specification? By extension what the differences between `void`, `ubyte`, `void[]`, `ubyte[]` really? The language documentation doesn't appear to be explaining everything.
[...]

One important difference between void[] and ubyte[] is that void[] may contain GC-scannable pointers, whereas ubyte[] is assumed to be pure data.  This may be important if you're storing live pointers in a buffer; if the buffer was allocated as a ubyte[], the GC might not scan it for pointers and may incorrectly collect live objects. (Though I'm not 100% sure the current GC implementation actually does this.)

Also, void means "no type", which is completely different from "ubyte", which means an unsigned 8-bit integer.  Some introspection operations like is(...) expressions return void when given an invalid expression, whereas returning ubyte means the expression evaluates to an 8-bit unsigned byte type.


T

-- 
What's a "hot crossed bun"? An angry rabbit.
July 17

On Wednesday, 16 July 2025 at 13:29:01 UTC, z wrote:

>

I also see this in the language documentation :

A void array cannot be indexed.

But i can slice it just fine in DMD 2.111...

Is this by design or is there a hole in the language specification?

The sentence before says:

>

Array indices in slicing operations are interpreted as byte indices

And the example shows slicing:

    void[] arr = data1;            // OK, int[] implicit converts to void[].
...
    arr[0..4] = [5];               // Assign first 4 bytes to 1 int element

Slicing a void array is useful as it can refer to multiple bytes. Indexing a void array is not really useful because if the array is only holding bytes, then why not use byte[] instead? If it's not a byte, then indexing it is probably wrong anyway (either by design, or because dealing with a single byte at a time is inefficient).

>

By extension what the differences between void, ubyte, void[], ubyte[] really? The language documentation doesn't appear to be explaining everything.
Thanks in advance

The docs explain the difference between the two array types. Perhaps there should be an entry for void in the types page. A void value cannot be accessed. void.sizeof is 1 so that a void array can have length equivalent to the number of bytes in the array.

July 17

On Thursday, 17 July 2025 at 16:26:43 UTC, Nick Treleaven wrote:

>

Perhaps there should be an entry for void in the types page. A void value cannot be accessed. void.sizeof is 1 so that a void array can have length equivalent to the number of bytes in the array.

https://github.com/dlang/dlang.org/pull/4261

July 17

On Wednesday, 16 July 2025 at 13:29:01 UTC, z wrote:

>

I also see this in the language documentation :

A void array cannot be indexed.

But i can slice it just fine in DMD 2.111...

You can slice it, meaning, getting a subarray out of it. However, indexing means getting a single element, which would be of type void if it was allowed.

>

By extension what the differences between void, ubyte, void[], ubyte[] really?

void[] is supposed to be an array pointing to data of unknown type. ubyte[] is supposed to be pointing to array of data bytes. The latter might also be used to point to other data arrays, such as wchar arrays, but they are never intended for pointing to anything that can't safely hold any binary value. So, if you have pointers, class references, classes, active reference counters or anything of that sort, it needs void[].

The language-level differences that come to mind:

  • You can read individual bytes of ubyte[] and change them. With void[] you cannot, unless you cast it to some other array type first.

  • The garbage collector, or the compiler, does not have to treat data pointed to by ubyte[] as potential pointers. With void[], the type isn't known so any optimisations or garbage collections have to assume the data might be pointers.

  • You won't be able to do much anything with void[] in @safe code. ubyte[] is very @safe friendly though, since it is assumed there is no danger of overwriting pointers or other type safety critical data.

July 18

On Thursday, 17 July 2025 at 18:56:08 UTC, Dukc wrote:

>
  • You won't be able to do much anything with void[] in @safe code.

Thanks, I realized that was missing from the docs. Copying into void[] is not allowed in @safe code.
https://github.com/dlang/dlang.org/pull/4262