The internal code of to currently breaks because ElementType!(void[0]) == void
Comment #1 by issues.dlang — 2018-03-08T17:38:39Z
Could you be more specific? What breaks? What's an example that doesn't compile when it should?
No array of void is a range (especially not a static one). So, if to were to support something like cast(ubyte[])voidArr, then it would need to special case the handling of void[], though I don't know if it's a great idea for to to support that sort of thing or not, since it's inherently unsafe, whereas to is generally supposed to be trying to do safe conversions, and all that such a conversion is going to do is cast.
Comment #2 by issues.dlang — 2018-03-08T17:39:48Z
Ah, the title gave what you were trying to do. I missed that. I'm not sure that I agree that it should work though, since it's unsafe and arguably should look that way, which is part of why casts are the way they are, with cast being very greppable.
Comment #3 by jack — 2018-03-08T17:41:30Z
(In reply to Jonathan M Davis from comment #2)
> Ah, the title gave what you were trying to do. I missed that. I'm not sure
> that I agree that it should work though, since it's unsafe and arguably
> should look that way, which is part of why casts are the way they are, with
> cast being very greppable.
Is it unsafe though? In this specific case of void[] to ubyte[] (or vise versa) isn't it ok?
Comment #4 by ag0aep6g — 2018-03-08T18:10:19Z
(In reply to Jack Stouffer from comment #3)
> Is it unsafe though? In this specific case of void[] to ubyte[] (or vise
> versa) isn't it ok?
void[] to ubyte[] is unsafe, because anything converts to void[]:
----
void f(int*[] p)
{
void[] v = p; /* This is considered @safe. Don't even need a cast. */
ubyte[] b = cast(ubyte[]) v; /* Just as unsafe as `cast(ubyte[]) p`. */
b[0] = 123; /* Messing with pointers like this is not safe. */
}
----
Comment #5 by jack — 2018-03-09T16:04:25Z
(In reply to ag0aep6g from comment #4)
> (In reply to Jack Stouffer from comment #3)
> > Is it unsafe though? In this specific case of void[] to ubyte[] (or vise
> > versa) isn't it ok?
>
> void[] to ubyte[] is unsafe, because anything converts to void[]:
>
> ----
> void f(int*[] p)
> {
> void[] v = p; /* This is considered @safe. Don't even need a cast. */
> ubyte[] b = cast(ubyte[]) v; /* Just as unsafe as `cast(ubyte[]) p`. */
> b[0] = 123; /* Messing with pointers like this is not safe. */
> }
> ----
Well the argument there is that the conversion from p to v should be unsafe, but not the conversion of v to b.
Comment #6 by ag0aep6g — 2018-03-09T16:45:17Z
(In reply to Jack Stouffer from comment #5)
> Well the argument there is that the conversion from p to v should be unsafe,
> but not the conversion of v to b.
Either or, I guess. Either you forbid going from pointers to void[], or you forbid going anywhere from void[]. As far as I see, both options provide safety, or does the second one have any holes?
DMD currently goes with the second option. Changing it would not be a small task, I think.
Comment #7 by issues.dlang — 2018-03-09T17:18:21Z
Going from void[] to anything is the safety problem, because that's when the data would potentially be reintrepreted incorrectly. Going to void[] from anything doesn't directly introduce @safety problems. It just strips out the ability to prevent them once converting to something else, because the type information has been lost. I believe that the normal thing to do with void[] is do something like write to a file or socket, in which case, it's arguably just an @safe way to convert arbitrary data to bytes rather than require an explicit cast (since the C API uses void* IIRC).
Either way, if you have void[] and are looking to do something with it other than hand it off to a C API that takes void* and writes bytes to some system resource, you need to know where it comes from and verify that the cast that you're doing is @safe.
Comment #8 by schveiguy — 2018-03-13T10:40:42Z
There are 2 possibilities I see for this:
1. It doesn't work, use a cast.
2. It should duplicate the array into a new ubyte array.
Simply doing the cast in std.conv.to is not acceptable, even in @system code, as it's equivalent to a possibly undefined-behavior inducing cast. to is supposed to be a "safe" cast.
It may be possible to allow a direct cast to const(ubyte)[].
Comment #9 by robert.schadek — 2024-12-01T16:33:00Z