This illustrates how a big-endian value is written on my little-endian machine. More explanation: the &0xff
part masks off all except the least signifcant 8 bits of the shifted value, although as I am unsure whether that or the (unsigned char)
are strictly necessary, I included a macro n2n()
without them as a comparison. Without them, I get no compiler warning and no error.
Also I have omitted the L
discussed in comments above. Note too that the pointer used must be an unsigned char
type - if it was an unsigned int
type, c
would be incremented by 4 (32-bit architecture). That's why I have used a union
to overlay the bytes.
The macro definition must have no space between its identifier and the first bracket. And finally if there seem to be more brackets than necessary in the macros, it is to ensure that any expression is correctly compiled, for example l2n(a+b,c);
#include <stdio.h>
#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
*((c)++)=(unsigned char)(((l)>>16)&0xff), \
*((c)++)=(unsigned char)(((l)>> 8)&0xff), \
*((c)++)=(unsigned char)(((l) )&0xff))
#define n2n(l,c) (*((c)++)=(l)>>24, \
*((c)++)=(l)>>16, \
*((c)++)=(l)>> 8, \
*((c)++)=(l) )
typedef union {
unsigned num;
unsigned char arr[4];
} bigend;
int main (void)
{
bigend number;
unsigned x;
char *p;
// test first macro
x = 0x12345678;
p = number.arr;
printf ("Input %08X\n", x);
l2n(x,p);
printf ("Output %08X\n\n", number.num);
// test second macro
x = 0x89ABCDEF;
p = number.arr;
printf ("Input %08X\n", x);
n2n(x,p);
printf ("Output %08X\n\n", number.num);
return 0;
}
Program output:
Input 12345678
Output 78563412
Input 89ABCDEF
Output EFCDAB89