Portability vs. Endianness

John F. Woods jfw at ksr.com
Thu Mar 14 05:23:10 AEST 1991


[One more time, this time with an open copy of ANSI C]

gwyn at smoke.brl.mil (Doug Gwyn) writes:
>In article <2628 at ksr.com> jfw at ksr.com (John F. Woods) writes:
>>This code is guaranteed.
>"Famous last words."
>In fact, it is not guaranteed on a host that uses ones-complement
>or sign-magnitude integral representation.

Hmm.  Actually, even more offensive is that my code fails if the number
of bits in a byte isn't 8 (fails in some sense, anyway; it does (on a
2s-complement 9-bit-per-byte machine) pick up the low 32 bits of the long,
which might be what's desired, but it doesn't pick up the low 4xbytesize
bits of the long, which might well be the idea).  In fact, it isn't
"guaranteed" even on a garden-variety, right-thinking, 8-bits-per-byte
2s-complement machine because "if E1 has a signed type and a negative
value, the resulting value is implementation-defined."  One hopes the
compiler will not generate code to launch a nuclear airstrike, but if
it is so documented in the vendor's manual, it is OK by ANSI.

Further hmm.  Is memcpy() obliged to do anything sensible if handed
a pointer to an integer cast to a void *?  The ANSI C spec refers to
memcpy() as working on "arrays of characters", and I know there have been
discussions where (for example) integers are placed in a different address
space from characters and hence a routine cannot assume that it can make any
use of "(char *)&integervalue".

Hmm again.  Now that I am staring at the ANSI manual, there's lots of
fascinating things here.  First, a conforming implementation is not
required to be able to represent "-0x80000000" in a signed long, but 
must be able to represent all 0x100000000 32-bit values in an unsigned long.
So, I think that the variable definitions should be changed to:

unsigned long var;
unsigned char Bytes[4];

Then

Bytes[0] = (var >> 24) & 0xFF;
Bytes[1] = (var >> 16) & 0xFF;
Bytes[2] = (var >> 8)  & 0xFF;
Bytes[3] =  var        & 0xFF;

Ought to give a consistent answer.  I think.  At least, I think it gives
the same answer on a 68000 and a DataBlaster-1000.

The problem specification is, I think, the real problem:  what, for example,
does it really *mean* to "want the value contained in var converted to a 68000
long word" on a 9 bit (or 1s-complement) machine?  If the goal is to printf
the four bytes with %x, I think the above solution is right in all cases;
if the goal is to write the data out on tape, then a 9-bit machine may not
be able to give a useful answer in any case.

I'm going to put "guarantee" into my spell-checker's list of "always
misspelled" words (well, I would if I used one...).



More information about the Comp.lang.c mailing list