www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to do "cast(ubyte[4])some_uint" in D1?

reply "Nick Sabalausky" <a a.a> writes:
In D2, I can treat a uint as an array of ubytes by doing this:

uint num = /+...whatever...+/;
ubyte[] = cast(ubyte[4])num;

How do I do that in D1?

IIRC, D1 requires an explicit slice operator to convert from a static-array 
to a slice/dynamic-array, so I tried this:

ubyte[] = (cast(ubyte[4])num)[];

But I get the error:
Error: e2ir: cannot cast num of type uint to type ubyte[4u]
Jun 02 2011
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Nick Sabalausky:

 In D2, I can treat a uint as an array of ubytes by doing this:
 
 uint num = /+...whatever...+/;
 ubyte[] = cast(ubyte[4])num;
 
 How do I do that in D1?

Using a union is probably the safest way: union Uint2Ubyte { uint u; ubyte[4] b; } By the way, this of type conversions is a shady area in D. Bye, bearophile
Jun 02 2011
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
 Nick Sabalausky:

 In D2, I can treat a uint as an array of ubytes by doing this:

 uint num = /+...whatever...+/;
 ubyte[] = cast(ubyte[4])num;

 How do I do that in D1?

Using a union is probably the safest way: union Uint2Ubyte { uint u; ubyte[4] b; } By the way, this of type conversions is a shady area in D. Bye, bearophile

I think it is no so shady after all: I tested the following code in DMD 2.053: void main(){ uint a; ubyte[] b = cast(ubyte[4])a; } It gives the same error as in D1. Timon
Jun 02 2011
parent reply "Nick Sabalausky" <a a.a> writes:
"Timon Gehr" <timon.gehr gmx.ch> wrote in message 
news:is7ojo$2ggv$1 digitalmars.com...
 Nick Sabalausky:

 In D2, I can treat a uint as an array of ubytes by doing this:

 uint num = /+...whatever...+/;
 ubyte[] = cast(ubyte[4])num;

 How do I do that in D1?

Using a union is probably the safest way: union Uint2Ubyte { uint u; ubyte[4] b; } By the way, this of type conversions is a shady area in D. Bye, bearophile

I think it is no so shady after all: I tested the following code in DMD 2.053: void main(){ uint a; ubyte[] b = cast(ubyte[4])a; } It gives the same error as in D1.

Ok, that's just bizarre. I've just check and verified that you're right. But I could swear I've done that sort of thing before, and without using the pointer trick Steve pointed out...
Jun 02 2011
parent "Nick Sabalausky" <a a.a> writes:
"Nick Sabalausky" <a a.a> wrote in message 
news:is8qu8$1cq3$1 digitalmars.com...
 "Timon Gehr" <timon.gehr gmx.ch> wrote in message 
 news:is7ojo$2ggv$1 digitalmars.com...
 Nick Sabalausky:

 In D2, I can treat a uint as an array of ubytes by doing this:

 uint num = /+...whatever...+/;
 ubyte[] = cast(ubyte[4])num;

 How do I do that in D1?

Using a union is probably the safest way: union Uint2Ubyte { uint u; ubyte[4] b; } By the way, this of type conversions is a shady area in D. Bye, bearophile

I think it is no so shady after all: I tested the following code in DMD 2.053: void main(){ uint a; ubyte[] b = cast(ubyte[4])a; } It gives the same error as in D1.

Ok, that's just bizarre. I've just check and verified that you're right. But I could swear I've done that sort of thing before, and without using the pointer trick Steve pointed out...

Ah ha! I figured out what I had done before. In D2, casting a struct to a same-sized static array works fine: struct Foo {uint f;} void main(){ Foo a; ubyte[] b = cast(ubyte[4])a; } Verified on DMD 2.053, 2.052 and 2.051. It doesn't work on D1 though (at least not 1.066 with tango trunk). But I'll try Steve's pointer trick for that. As a nice touch, it fails in D2 if you change the "ubyte[4]" to "ubyte[5]". Using "ubyte[3]" is prohibited, too, even though I would think that should be ok. But that's probably not a real big deal. But...it seems strange that casting a primitive to a static array would be prohibited if it's perfectly kosher when the primitive is in a struct. So I've filed a bug report on that: Can't cast primitive to same-sized static array http://d.puremagic.com/issues/show_bug.cgi?id=6092
Jun 02 2011
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 02 Jun 2011 05:35:40 -0400, Nick Sabalausky <a a.a> wrote:

 In D2, I can treat a uint as an array of ubytes by doing this:

 uint num = /+...whatever...+/;
 ubyte[] = cast(ubyte[4])num;

 How do I do that in D1?

 IIRC, D1 requires an explicit slice operator to convert from a  
 static-array
 to a slice/dynamic-array, so I tried this:

 ubyte[] = (cast(ubyte[4])num)[];

 But I get the error:
 Error: e2ir: cannot cast num of type uint to type ubyte[4u]

We can learn from C here :) ubyte[] x = (cast(ubyte *)&num)[0..4]; Essentially, pointers are *always* castable to one another, and do not go through any translations. Go to pointer-land, then back, and all your casts shall work. It's how C++'s reinterpret_cast works. -Steve
Jun 02 2011