Setting Bitfields on big endian and little endian

R

Ramesh

Hi

I have a structure as below on big endian based system

typedef struct
{

unsigned long LedA:5;
unsigned long LedB:4;
unsigned long LedC:8;
unsigned long LedD:4;
unsigned long LedE:5;
unsigned long LedF:6;

}regs_t;

#define get_LedStatus(x) ((regs_t *)(&x))->LedA

main() {

unsigned long LedReg = 0x80000000;
printf("%X", get_LedStatus(LedReg))

}

On a big endian based system - I get a value of 0x1 as output.

For the little endian based system, I define the structure as below:

typedef struct
{

unsigned long LedF:6;
unsigned long LedE:5;
unsigned long LedD:4;
unsigned long LedC:8;
unsigned long LedB:4;
unsigned long LedA:5;

}regs_t;

I get a value as 0x10, so instead of getting a bit pattern like 0
0001
what I get is 1 0000

While reversing the bits solves the problem - Any insights as to what
could be the best solution if I have several such structures to be
ported from big endian to little endian system?

BTW the target is Linux 2.6 on x86 & gcc 4.12.2xxxx

Thanks
/R
 
B

Barry Schwarz

Hi

I have a structure as below on big endian based system

typedef struct
{

unsigned long LedA:5;

unsigned long is not one of the standard types allowed for bit-fields.
Does your implementation actually document it as an extension as
required by 6.7.2.1-4.
unsigned long LedB:4;

You need to look at 6.7.2.1-10 to see the possible implementations
when two adjacent bit-fields won't fit in a byte.. Which one does
your implementation document?

The same section talks about the order in which bit fields are
defined. Which one does your implementation document?
unsigned long LedC:8;
unsigned long LedD:4;
unsigned long LedE:5;
unsigned long LedF:6;

}regs_t;

#define get_LedStatus(x) ((regs_t *)(&x))->LedA

main() {

unsigned long LedReg = 0x80000000;
printf("%X", get_LedStatus(LedReg))

%X expects its argument to be an unsigned int. You invoke undefined
behavior by passing an unsigned long.
}

On a big endian based system - I get a value of 0x1 as output.

You need to show the actual output. %X does not produce a leading 0x.
Are you sure your code as seven zeros after the eight in the
initialization value. If so, I would have expected output of 10.
Your output makes sense if there are only 6 zeros.

Is a long actually 32 bits on your system? Shouldn't your
initialization value have UL affixed?
For the little endian based system, I define the structure as below:

typedef struct
{

unsigned long LedF:6;
unsigned long LedE:5;
unsigned long LedD:4;
unsigned long LedC:8;
unsigned long LedB:4;
unsigned long LedA:5;

}regs_t;

I get a value as 0x10, so instead of getting a bit pattern like 0
0001
what I get is 1 0000

While reversing the bits solves the problem - Any insights as to what
could be the best solution if I have several such structures to be
ported from big endian to little endian system?

If you define the structure with an unsigned integer of the correct
size, you can use the <<, >>, and && operators to extract the desired
fields. Since they work on values and not representations, you may be
able to ignore the problem of endianness altogether.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top