Thread overview | |||||
---|---|---|---|---|---|
|
March 18, 2017 Enums and immutables | ||||
---|---|---|---|---|
| ||||
Hello. I found strange behavior while casting enum array and immutable array. import std.stdio; void main() { enum arr = cast(ubyte[])[0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,4]; auto arr1 = cast(void[])arr; immutable arr2 = cast(immutable(void)[])arr; enum arr3 = cast(void[])arr; writeln(cast(ushort[])arr1); // [0, 256, 0, 512, 0, 768, 0, 1024] writeln(cast(ushort[])arr2); // [0, 256, 0, 512, 0, 768, 0, 1024] writeln(cast(ushort[])arr3); // [0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4] } I think it's related to representation of enums by compiler as #define. It's right? It's behavior by design? |
March 19, 2017 Re: Enums and immutables | ||||
---|---|---|---|---|
| ||||
Posted in reply to Oleg B | On 19/03/2017 1:22 AM, Oleg B wrote:
> Hello. I found strange behavior while casting enum array and immutable
> array.
>
> import std.stdio;
>
> void main()
> {
> enum arr = cast(ubyte[])[0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,4];
>
> auto arr1 = cast(void[])arr;
> immutable arr2 = cast(immutable(void)[])arr;
> enum arr3 = cast(void[])arr;
>
> writeln(cast(ushort[])arr1); // [0, 256, 0, 512, 0, 768, 0, 1024]
> writeln(cast(ushort[])arr2); // [0, 256, 0, 512, 0, 768, 0, 1024]
> writeln(cast(ushort[])arr3); // [0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3,
> 0, 0, 0, 4]
> }
>
> I think it's related to representation of enums by compiler as #define.
> It's right? It's behavior by design?
It took me a bit but what I thinking happening is 1 and 2 are being casted at runtime where as 3 is at CT.
At CT its per value of the enum array, at RT its per x bytes from array. Which sort of makes sense as at CT it does know the type even if you did cast it to void[].
|
March 18, 2017 Re: Enums and immutables | ||||
---|---|---|---|---|
| ||||
Posted in reply to Oleg B | On 03/18/2017 01:22 PM, Oleg B wrote: > enum arr = cast(ubyte[])[0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,4]; > > auto arr1 = cast(void[])arr; > immutable arr2 = cast(immutable(void)[])arr; > enum arr3 = cast(void[])arr; Aside: The casts here do nothing to affect the outcome. > writeln(cast(ushort[])arr1); // [0, 256, 0, 512, 0, 768, 0, 1024] > writeln(cast(ushort[])arr2); // [0, 256, 0, 512, 0, 768, 0, 1024] > writeln(cast(ushort[])arr3); // [0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, > 0, 0, 0, 4] I guess the last one here is supposed to be the surprising one. I find them all surprising, actually. `arr` itself is already not what I'd expect. It should be an array with 64 elements, because you're casting an array of 16 int elements to ubyte[] (16 * int.sizeof = 64). At least that's how it works with a run-time array: auto a = [0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,4]; auto b = cast(ubyte[]) a; assert(b.length == 64); But when the source is a literal or an enum, the cast doesn't change the length. Instead the elements are casted individually. I'd call this a bug. It's definitely surprising. It's also potentially throwing data away: writeln(cast(ubyte[]) [257, 2, 3, 4]); /* [1, 2, 3, 4] */ Run-time array casts don't do that. |
Copyright © 1999-2021 by the D Language Foundation