Bug 8901 – a bug to cast from array literal to ubyte[]

Status
RESOLVED
Resolution
INVALID
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2012-10-27T06:22:19Z
Last change time
2023-02-08T22:51:30Z
Assigned to
No Owner
Creator
Kazuki Komatsu
See also
https://issues.dlang.org/show_bug.cgi?id=16207

Comments

Comment #0 by enjouzensyou.boinc — 2012-10-27T06:22:19Z
import std.stdio; void main() { int a = 12321; int[] arr = [a]; assert( (cast(ubyte[])[a]) == (cast(ubyte[])arr) ); } This code doesn't work!
Comment #1 by hsteoh — 2012-10-27T13:21:36Z
I don't understand, why should this work? D arrays are not the same as C arrays; casting an int into an array does not magically make it an array of bytes. If you want to get the byte representation, you need to do something like this: int a = 1234; ubyte* ptr = cast(ubyte*)&a; writeln(ptr[0 .. int.sizeof]); Note, though, that this is unsafe, and is generally not recommended in D code, unless you're writing low-level code.
Comment #2 by hsteoh — 2012-10-27T13:26:15Z
Haha, case in point: that slice operation should be ptr[0 .. int.sizeof-1].
Comment #3 by hsteoh — 2012-10-27T13:27:15Z
Oh wait, no, the original was correct. :-/ See what I mean? It's unsafe. :)
Comment #4 by zan77137 — 2012-10-28T04:54:11Z
This is like the bug somehow or other. However, by the document of the Web, it does not seem to be touched about the explicit cast from array to array deeply. In the current implementation, it is worked by _d_arraycast in druntime. The cast is performed safely, and it throws Error if misalignment occurs. This bug seems to happen, because `cast(ubyte[])[a]` is processed as `cast(ubyte[])[cast(ubyte)a]` by dmd. `[a]` should be always processed as `int[]`.
Comment #5 by yebblies — 2012-10-28T11:19:42Z
(In reply to comment #4) > > This bug seems to happen, because `cast(ubyte[])[a]` is processed as > `cast(ubyte[])[cast(ubyte)a]` by dmd. > `[a]` should be always processed as `int[]`. That is not a bug, casting an array literal is not the same as casting an array/slice. While this is an inconsistent design, it is definitely intentional.
Comment #6 by Ajieskola — 2023-02-08T17:20:43Z
I was just bitten by this one. Test case: ------------------ void main() { import std.stdio; // Excepted: 1 on big endian machine, 0 on little endian machine // Got: Error: array index 3 is out of bounds `[cast(ubyte)1u][0 .. 1] (cast(ubyte[]) [1])[3].writeln(); } ------------------ Maybe this is behaving as intended, but if so, I'm unable to find the spec rule that says so. Instead https://dlang.org/spec/expression.html#array_literals says that array literals are dynamic arrays of common type of their element. Reopening until the spec and implementation match.
Comment #7 by snarwin+bugzilla — 2023-02-08T22:51:30Z
This behavior is documented in the "Casting" subsection of the "Array Literals" section of the language spec [1]: > When array literals are cast to another array type, each element of the array is cast to the new element type. When arrays that are not literals are cast, the array is reinterpreted as the new type, and the length is recomputed According to the git history, this paragraph was introduced in 2009 by commit 8f99bfef0. So this has been the intended, documented behavior since before this issue was first opened. [1] https://dlang.org/spec/expression.html#cast_array_literal [2] https://github.com/dlang/dlang.org/commit/8f99bfef0#diff-38fe074d968a576648917dd82d0a11b502f2a8f35e39f920e929dbd6a4d2b407