Portability vs. Endianness
Blair P. Houghton
bhoughto at hopi.intel.com
Wed Mar 13 13:26:57 AEST 1991
In article <1991Mar12.105451.19488 at dit.upm.es> esink at turia.dit.upm.es () writes:
>long var;
>unsigned char Bytes[4];
>
>Is there a portable way to move the value held in var
>into the memory space pointed to by Bytes, with the restriction
>that the representation be in Most Significant Byte first
>format ? I am well aware that sizeof(long) may not be 4. I
#if (((sizeof long)%(sizeof char)) == 0) /* even-numbered modulus */
/*
* Don't forget; chars _can_ be the same number of bits
* as longs, and longs _can_ be an odd number of bytes.
*
* Give'em an inch, and...
*/
#define LONGWORD sizeof long
#define HALFWORD LONGWORD/2
/* Memcpy(3) is the neat way. */
#include <string.h>
long var;
unsigned char Bytes[LONGWORD];
char *p;
p = (char *)&var;
memcpy( (void *)(Bytes+HALFWORD), (void *)p, HALFWORD); /* front to back */
memcpy( (void *)Bytes, (void *)(p+HALFWORD), HALFWORD); /* back to front */
/* to avoid using p: */
long var;
unsigned char Bytes[LONGWORD];
memcpy((void *)(Bytes+HALFWORD),(void *)&var,HALFWORD); /* front to back */
memcpy((void *)Bytes,(void *)((char *)&var+HALFWORD),HALFWORD); /*b-f*/
/* but when you don't have the ANSI library or a bcopy(3), */
long var;
unsigned char Bytes[LONGWORD];
char *p;
int n;
/* front to back, then back to front */
for ( p = (char *)&var; p < LONGWORD + (char *)&var; p += HALFWORD )
for ( n = ((char *)&var + HALFWORD) - p); /* Halfword, then 0 */
n < ((char *)&var + LONGWORD) - p); /* Longword, then Halfword */
n++ )
Bytes[n] = *p;
/*
* Of course, since this applies architecturally, you can
* wrap it in machine names and simplify until you're silly,
* using those porridges of code above only for the default
* (unknown wordsize) case.
*/
#ifdef BLEET_TO_BLIT
/* both: 16-bit chars, 32-bit longs; bleet: little; blit: big */
long var;
unsigned char Bytes[2];
Bytes[0] = *(char *)var;
Bytes[1] = *((char *)var + 1);
#endif
#endif
The basic answer to your underlying question is, yes, you
can access the individual bytes of any object in ANSI C;
i.e., all objects must have n*CHAR_BIT bits, where n is
some positive integer. See ANSI X3.159-1989 (i.e., the
standard), sections 1.6 (for "Object"), 2.2.4.2.1 (for
"CHAR_BIT"), and the Rationale, section 1.6 (for more on
the multiples-of-bytes theme).
--Blair
"AND, it has the added BONUS of
being able to convert the big-
endian BACK into little-endian
when you're DONE with it! :-)"
More information about the Comp.lang.c
mailing list