I made this union, in order to easily access, back and forth, between bits and integer. (in fact, I looked for a way to r/w all bits of a signed int, easily, without portability pitfall, I screwed myself nicely)
typedef union {
struct {
unsigned int b32 : 1;
unsigned int b31 : 1;
unsigned int b30 : 1;
unsigned int b29 : 1;
unsigned int b28 : 1;
unsigned int b27 : 1;
unsigned int b26 : 1;
unsigned int b25 : 1;
unsigned int b24 : 1;
/* etc. */
unsigned int b01 : 1; /* LSB */
} field;
uint32_t word;
int32_t integer;
} Bit32Field_T;
As expected, each bxx field give me access to the bits of the underlying 32 byte integer.
This code however, is only valid for a sparc (big endian) CPU. For little-endian ones (x86) I have to mirror each fields, from b01 to b32, in order to get the expected behavior.
typedef union {
struct {
unsigned int b01 : 1; /* LSB */
unsigned int b02 : 1;
unsigned int b03 : 1;
unsigned int b04 : 1;
unsigned int b05 : 1;
unsigned int b06 : 1;
unsigned int b07 : 1;
unsigned int b08 : 1;
unsigned int b09 : 1;
/* etc. */
unsigned int b32 : 1;
} field;
uint32_t word;
int32_t integer;
} Bit32Field_T;
I thought little-endianness was about reversing bytes not bits ! How should I understand the bit packing made ?
(everything compiled with gcc, under solaris for the BE, debian for the LE)
My approach for a similar problem, i.e. converting a 32 bit word from little to big-endian, was:
unsigned char buf[4];
uint32_t word;
fread(buf, sizeof(buf), 1, fp);
word = buf[0] |
(buf[1] << 8) |
(buf[2] << 16) |
(buf[3] << 24);
I agree it is bizarre that your code worked, I would have expected the approach suggested by Pickif would be what is required
Prob worth taking M Oehm s advice on extracting bits if it is compiler dependent and not something to do with the hardware and ditch the union approach