Subject: Re: htonl and longs
To: None <simonb@netbsd.org, tv@pobox.com>
From: Ross Harvey <ross@ghs.com>
List: port-alpha
Date: 06/18/1999 10:11:58
> From: Todd Vierling <tv@pobox.com>
>
> : I'm looking at making the fortune data files byte-order and word-size
> : independant, and came across the following in fortune's .dat convertor:
> : 
> : 	simonpc:games/fortune/strfile 32> grep str_version *
> : 	strfile.c:      Tbl.str_version = VERSION;
> : 	strfile.c:      Tbl.str_version = htonl(Tbl.str_version);
> : 	strfile.h:      unsigned long   str_version;            /* version number */
> : 
> : Given that htonl is defined to work on the equivalent of u_int32_t's and
> : unsigned longs are 64 bits, and I right in assuming that the behaviour
> : of this bit of code is bogus at best?
>
> htonl works on longs, not u_int32_t's.  This may sound Odd at first, but
> it's absolutely true.
>
> On a little-endian ILP32 machine, the integer 0x11223344 is represented by
> 0x44332211 in memory, and is stored as 0x11223344 after running through
> htonl() (this is the usual, expected behavior).
>
> On little-endian LP64, it's a little more strange.  The integer 0x11223344
> is represented by 0x4433221100000000 in memory, and after running through
> htonl(), becomes 0x0000000011223344.
>
> If the unsigned long above should be machine, independent, then the htonl()
> has to be calculated on a *LOCAL* long variable (otherwise you'll lose the
> necessary 32 bits on the first store), and then stored into a u_int32_t in
> the structure.

Interesting theory...I'm kind of intrigued as to how you got there.

Those are what I call ``legacy longs'', or 32-bit objects. It's just a bad
name, these days. (This is all because DEC called int16_t a ``word'' on
the VAX, darn it!)

Even if you do call htonl(3) on a real alpha long, it still does what you
expect, and does everything in the low order 32 bits.

	0x0000000011223344	<->	0x0000000044332211
	0x11223344		<->	0x44332211

The only time you see something like 0x4433221100000000 is if you are
looking at an LP64 long or ILP32 ``long long'' from a foreign and opposite
swizzle machine. But this doesn't actually happen in any network code I've
seen, and in any case it isn't valid input to htonl which will completely
butcher it, leaving you with zero as it swizzles just the lower 32 bits.

	Ross.Harvey@Computer.Org