digitalmars.D - correct way to split int into bytes?
- newbie d.com (16/16) Dec 01 2004 Without bit shifting, what's the correct way to split a int (32-bits) in...
- Ben Hinkle (13/29) Dec 01 2004 specification
- Thomas Kuehne (23/48) Dec 01 2004 -----BEGIN PGP SIGNED MESSAGE-----
- newbie d.com (11/14) Dec 01 2004 Haa! why you only mention gdc? actually that test fails for all the com...
- Thomas Kuehne (21/29) Dec 01 2004 -----BEGIN PGP SIGNED MESSAGE-----
- newbie d.com (10/15) Dec 01 2004 Sorry. But are you refering to the linker? then I'm confused: is this a
- Dr.Dizel (9/12) Dec 01 2004 Hm. I use this:
- Thomas Kuehne (19/37) Dec 01 2004 -----BEGIN PGP SIGNED MESSAGE-----
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (29/41) Dec 02 2004 Something like this: (ands are optional)
Without bit shifting, what's the correct way to split a int (32-bits) into 4 bytes? BTW, I don't care about the byte order: union U { int i; struct { byte a, b, c, d; } } U u; void splitInt32( int x ) { u.i = x; // use the bytes ... anotherFunc( u.a, u.b, u.c, u.d ); } Will this code work with DMD and GDC? And does the D language specification guarantee this code will always work, so I don't have to worry about every other potential compiler implementations in the future? Thanks.
Dec 01 2004
<newbie d.com> wrote in message news:col0rk$1kj$1 digitaldaemon.com...Without bit shifting, what's the correct way to split a int (32-bits) into4bytes? BTW, I don't care about the byte order: union U { int i; struct { byte a, b, c, d; } } U u; void splitInt32( int x ) { u.i = x; // use the bytes ... anotherFunc( u.a, u.b, u.c, u.d ); } Will this code work with DMD and GDC? And does the D languagespecificationguarantee this code will always work, so I don't have to worry about everyotherpotential compiler implementations in the future? Thanks.With the struct I think D can insert padding between the bytes to get appropriate alignment - though I don't remember exactly what the spec says about that. It might be better to cast to a byte* and use array indexing. int main() { int x = 0x11223344; byte* y = cast(byte*)&x; printf("%x %x %x %x \n",y[0],y[1],y[2],y[3]); return 0; }
Dec 01 2004
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Ben Hinkle schrieb am Wed, 1 Dec 2004 13:55:19 -0500:<newbie d.com> wrote in message news:col0rk$1kj$1 digitaldaemon.com...Without bit shifting, what's the correct way to split a int (32-bits) into 4 bytes? BTW, I don't care about the byte order: union U { int i; struct { byte a, b, c, d; } } U u; void splitInt32( int x ) { u.i = x; // use the bytes ... anotherFunc( u.a, u.b, u.c, u.d ); } Will this code work with DMD and GDC? And does the D language specification guarantee this code will always work, so I don't have to worry about every other potential compiler implementations in the future?With the struct I think D can insert padding between the bytes to get appropriate alignment - though I don't remember exactly what the spec says about that.In theory, that's what the align keyword is for: In praxis ... http://svn.kuehne.cn/dstress/www/dstress.html#align_06 indicates that the align keyword has no effect when used with gcc(for linking under Linux). Thomas -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.9.12 (GNU/Linux) iD8DBQFBrhjY3w+/yD4P9tIRAq+4AKC9RQTtkbQepBLrgNe2iOIhDv8ppQCfXGjI rVpVsYaY4Q6ecVvd5ilBnQU= =PXIH -----END PGP SIGNATURE-----
Dec 01 2004
In article <ovh182-ev4.ln1 kuehne.cn>, Thomas Kuehne says...In praxis ... http://svn.kuehne.cn/dstress/www/dstress.html#align_06 indicates that the align keyword has no effect when used with gcc(for linking under Linux).Haa! why you only mention gdc? actually that test fails for all the compiler versions: -------------------------------------------------------------------- dmd 0.93 dmd 0.95 dmd 0.96 dmd 0.98 dmd 0.99 dmd 0.100 dmd 0.101 dmd 0.102 gdc 1g dmd 0.104 gdc 0.8 gdc 0.8 Mac dmd 0.105 dmd 0.106 dmd 0.108 -------------------------------------------------------------------- align 06 fail fail fail fail fail fail fail fail fail fail fail fail fail fail fail --------------------------------------------------------------------
Dec 01 2004
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 newbie d.com schrieb am Wed, 1 Dec 2004 20:27:11 +0000 (UTC):In article <ovh182-ev4.ln1 kuehne.cn>, Thomas Kuehne says...<snip> Please read again I wrote GCC, not GDC. On Windows you usually compile with DMD and link the objects/libraries with DMC. DMC doesn't support Linux, thus Linux users have to use other means. GCC is the common choice. GDC is not involved during DMD->GCC building on Linux, but is a compiler on it's own. I haven't got a Windows box, thus can't test it myself. If you are interested in "align" under Windows, I'd suggest you download http://svn.kuehne.cn/dstress/run/align_06.d , compile, link, execute and report back. Thomas -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.9.12 (GNU/Linux) iD8DBQFBrjET3w+/yD4P9tIRAgSwAKDF68sOkLLpyhCx6llklLXTof8YVgCcCLpD mQH+ZdvYyl2cSuYa65wLk7s= =AwMO -----END PGP SIGNATURE-----In praxis ... http://svn.kuehne.cn/dstress/www/dstress.html#align_06 indicates that the align keyword has no effect when used with gcc(for linking under Linux).Haa! why you only mention gdc? actually that test fails for all the compiler versions:
Dec 01 2004
In article <j1o182-7u5.ln1 kuehne.cn>, Thomas Kuehne says...Please read again I wrote GCC, not GDC.Sorry. But are you refering to the linker? then I'm confused: is this a compiler issue, or linking issue?I haven't got a Windows box, thus can't test it myself. If you are interested in "align" under Windows, I'd suggest you download http://svn.kuehne.cn/dstress/run/align_06.d , compile, link, execute and report back.Tried, and failed: D:\tmp>align_06.exe Error: AssertError Failure align_06.d(17) Now I think my question is: given the current compiler implementation, what's the fastest way (in theory) to split int into bytes? bit-shifting, or array indexing by casting to (byte*). Haven't done the experient yet, like to hear your opinion (in theory) first.
Dec 01 2004
Now I think my question is: given the current compiler implementation, what's the fastest way (in theory) to split int into bytes? bit-shifting, or array indexing by casting to (byte*).Hm. I use this: align(1) union int2bytes { uint theInt; ubyte[4] theBytes; static assert (int2bytes.sizeof == 4); static assert (int2bytes.alignof == 1); } Is it good? :)
Dec 01 2004
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 newbie d.com schrieb am Wed, 1 Dec 2004 21:31:40 +0000 (UTC):Usually I would expect this to be a compiler issue, but it might as well be a "communication" within the toolchain. The Linux "linking" stage for D involves more than just plain linking via LD.Please read again I wrote GCC, not GDC.Sorry. But are you refering to the linker? then I'm confused: is this a compiler issue, or linking issue?Hurry up and send a bug report to the digitalmars.D.bugs newsgroup ;)I haven't got a Windows box, thus can't test it myself. If you are interested in "align" under Windows, I'd suggest you download http://svn.kuehne.cn/dstress/run/align_06.d , compile, link, execute and report back.Tried, and failed: D:\tmp>align_06.exe Error: AssertError Failure align_06.d(17)Now I think my question is: given the current compiler implementation, what's the fastest way (in theory) to split int into bytes? bit-shifting, or array indexing by casting to (byte*). Haven't done the experient yet, like to hear your opinion (in theory) first.Do you use constant values for indexing / bit-shifting? ( x[2] / x>>16 versus x[n] / x>>n ) Don't you intend to effectifly use byte-shifts instead of bit-shifts? ( x>>(8*n) insted of x>>m; n,m=[0,1,..]) Compile some samples and have a look at the assembler output. Thomas -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.9.12 (GNU/Linux) iD8DBQFBrkS/3w+/yD4P9tIRAm7iAKCIKYu3CEXFraqHRtJOwDNWGhLuPACgtY0Z s2jPIjcEX2xjUl2F4H4P/xo= =bn+g -----END PGP SIGNATURE-----
Dec 01 2004
newbie d.com wrote:Without bit shifting, what's the correct way to split a int (32-bits) into 4 bytes?Why *not* use regular bit shifting ?uint i; ubyte[4] b;Something like this: (ands are optional) 1)b[0] = (i >>> 24); b[1] = (i >>> 16) & 0xFF; b[2] = (i >>> 8) & 0xFF; b[3] = i & 0xFF;It's probably a whole lot easier... ? Not to mention faster, avoids storing. (going to memory is bound to be slow) But you could do that too, if you like: 2)*(cast(uint*) b) = i;Or with a union, to avoid the casting. (beware of union/alignment bugs, though) Or you could just use a byte pointer instead of a new variable, then you only need to cast the int pointer... (either to a temp, or when using it)ubyte* b;3)b = cast(ubyte*) &i;Then you can use b[0] just as with an array. ("static array", that is, such as ubyte[4]) Or depending on what you want it for, you could use 4 variables instead of an array to "help" the compiler avoid storing them in memory but use the registers instead ?ubyte b0,b1,b2,b3;And then just use "b0" instead of "b[0]", when bitshifting from the 32-bit integer. But smart compilers should do that anyway. At the end of the day, it depends on *why* you want to split it and what to use it for? --anders PS. These three examples do work with GDC.
Dec 02 2004