With monday.comâ€™s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

I'm using a data structure in C like the following that contains a bit field and uses the colon to define the number of bits.

typedef bitfield{

uchar x:6,

uchar y:2;

uchar z;

} BITFIELD;

//assume msb packing such that x is 6 most significant bits and y is 2 least sig. bits

In my code if I have a byte value and then assign it to the type members, will the least significant bits always be assigned to the bit field variable, or, will the assignment take into account the correct number of bits as shown below?

//pseudo code

BITFIELD mybitfield;

uchar data = 0xFC; // 1111 1100

mybitfield.x = data;

mybitfield.y = data;

mybitfield.z = data;

at this point I think the following values are stored

mybitfield.x = 0x3F //111111 six most sig. bits

mybitfield.y = 0x00 //00 two least sig. bits

mybitfield.z = 0xFC

Is this correct?

Thanks.

typedef bitfield{

uchar x:6,

uchar y:2;

uchar z;

} BITFIELD;

//assume msb packing such that x is 6 most significant bits and y is 2 least sig. bits

In my code if I have a byte value and then assign it to the type members, will the least significant bits always be assigned to the bit field variable, or, will the assignment take into account the correct number of bits as shown below?

//pseudo code

BITFIELD mybitfield;

uchar data = 0xFC; // 1111 1100

mybitfield.x = data;

mybitfield.y = data;

mybitfield.z = data;

at this point I think the following values are stored

mybitfield.x = 0x3F //111111 six most sig. bits

mybitfield.y = 0x00 //00 two least sig. bits

mybitfield.z = 0xFC

Is this correct?

Thanks.

typedef bitfield{

uchar x:6,

y:2;

uchar z;

} BITFIELD;

(note the comma after the 6)

mybitfield.x = 0x3C

mybitfield.y = 0x00

mybitfield.z = 0xFC

This is what I would expect no matter what internal representation your compiler would have.

uchar data = 0xFC; // 1111 1100

taking the 6 bits of data gives 11 1100 which is 3C

taking the 2 bits of data gives 00 which is 0

taking the 8 bits of data of course gives data which is 0xFC;

Second, bit fields, pretty much act like integers of a limited width, so assigning a value to a bit field, is like assigning a value to an integer (of the same type as the one used for the bit field), so :

>> mybitfield.x = 0x3F //111111 six most sig. bits

the result would be 0x3C, rather than 0x3F.

structure shall be packed into adjacent bits of the same unit. If insufficient space remains,

whether a bit-field that does not fit is put into the next unit or overlaps adjacent units is

implementation-defined. The

addressable storage unit is unspecified."

I'm using this for a communications protocol, specifically IPMI. This type of structure is used in the open source coreIPM software.

With my platform being a big endian ARM processor I expect the six bits will be the msb's.

Because this is an unsigned char and there are no other bit fields in the structure, I'm feeling like it's pretty safe, but I agree shifting and masking seems safer.

typedef struct

{

unsigned short a:4;

unsigend short b:4;

unsigned short c: 4;

unsigned short d:4;

unsigned char e;

}some_struct;

......will NOT be 24 bytes in size (where a short is 2 bytes and a char is 1 byte). It will actually be 32 bytes, because the compiler will pad it. The size of structs are very important in comm software, so you can see where this would be a problem, especially if you're dealing with messages that are an odd number in size.

That struct will NOT be 3 bytes in size (or 24 bits). It will actually be 4 bytes in size (32 bits).

Usually big endian refers to byte order rather than bit order. So, while the six bits might be the msb's, in general, on a big endian machine, it doesn't have to be. For that matter, there would not have been a contradiction if I found that the 6 bits were allocated in the msb's. It's platform dependent. In fact, by platform, I believe that really means compiler dependent. So, on the same machine, two different compiler vendors would have the right, I think, to allocate the internal bit allocation in any group as they wish subject to the restrictions in the above C99 quote that I referenced.

>> at this point I think the following values are stored

>> <SNIP>

>> Is this correct?

This has nothing to do with how the bit fields are allocated within the struct. The only two posts that answer this correctly, are http:#29269068 and http:#29269146.

So, be careful to not draw the wrong conclusions here.

All Courses

From novice to tech pro — start learning today.

x:6 are the 6 lsb of the first byte

y:2 are the 2 msb of the first byte

z is the 2nd byte

But, as I mentioned earlier, the layout is implementation dependent; so it could be different on your platform. For example, it could be that on your platform x:6 is the 6 msb of the first byte.

If you are planning on trying to use this bit-field approach for memory-mapped registers, then (1) I would be extremely careful; and (2) I would seriously consider using a more portable approach where you definitely control which bits are set.

In other words, if you care about where the bit-fields are placed in the word, then I would advise not using bit-fields.