convert ubyte[k..k + 1] to int

H. S. Teoh hsteoh at quickfur.ath.cx
Wed May 16 21:07:48 PDT 2012


On Wed, May 16, 2012 at 10:25:51PM -0500, Andrew Wiley wrote:
> On Wed, May 16, 2012 at 11:03 AM, Regan Heath <regan at netmail.co.nz> wrote:
> 
> > On Wed, 16 May 2012 15:24:33 +0100, ref2401 <refactor24 at gmail.com> wrote:
> >
> >  i have an array of ubytes. how can i convert two adjacent ubytes from the
> >> array to an integer?
> >>
> >> pseudocode example:
> >> ubyte[5] array = createArray();
> >> int value = array[2..3];
> >>
> >> is there any 'memcpy' method or something else to do this?
> >>
> >
> > You don't need to "copy" the data, just tell the compiler to "pretend"
> > it's a short (in this case, for 2 bytes) then copy the value/assign to an
> > int. e.g.
> >
> > import std.stdio;
> >
> > void main()
> > {
> >        ubyte[5] array = [ 0xFF, 0xFF, 0x01, 0x00, 0xFF ];
> >        int value = *cast(short*)array[2..3].ptr;
> >        writefln("Result = %s", value);
> > }
> >
> > The line:
> >  int value = *cast(short*)array[2..3].ptr;
> >
> > 1. slices 2 bytes from the array.
> > 2. obtains the ptr to them
> > 3. casts the ptr to short*
> > 4. copies the value pointed at by the short* ptr to an int
> >
> > You may need to worry about little/big endian issues, see:
> > http://en.wikipedia.org/wiki/**Endianness<http://en.wikipedia.org/wiki/Endianness>
> >
> > The above code outputs "Result = 1" on my little-endian x86 desktop
> > machine but would output "Result = 256" on a big-endian machine.
> >
> > R
> >
> >
> Unfortunately, this is undefined behavior because you're breaking
> alignment rules. On x86, this will just cause a slow load from memory.
> On ARM, this will either crash your program with a bus error on newer
> hardware or give you a gibberish value on ARMv6 and older.
> Declaring a short, getting a pointer to it, and casting that pointer
> to a ubyte* to copy into it is fine, but casting a ubyte* to a short*
> will cause a 2-byte load from a 1-byte aligned address, which leads
> down the yellow brick road to pain.

Do unions suffer from this problem? Could this prevent alignment
problems:

	short bytesToShort(ubyte[] b)
	in { assert(b.length==2); }
	body {
		union U {
			short val;
			ubyte[2] b;
		}
		U u;

		u.b[] = b[];
		return u.val;
	}

?


T

-- 
Береги платье снову, а здоровье смолоду. 


More information about the Digitalmars-d-learn mailing list