www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - void[] vs ubyte[] - differences?

reply z <z z.com> writes:
```D
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
Jul 16
next sibling parent "H. S. Teoh" <hsteoh qfbox.info> writes:
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.
Jul 16
prev sibling next sibling parent reply Nick Treleaven <nick geany.org> writes:
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: ```d 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.
Jul 17
parent Nick Treleaven <nick geany.org> writes:
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
Jul 17
prev sibling parent reply Dukc <ajieskola gmail.com> writes:
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.
Jul 17
parent Nick Treleaven <nick geany.org> writes:
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
Jul 18