talel talel - 17 days ago 5
C Question

struct/class bit field packing

I'd like to use the bit field feature of cpp.

However i get all kind of strange behivours and i was wondering if there is

a way to constrain the compiler.


I'd like to use this bit field:


class MyBitField
{
uint32 a : 8;
uint32 b : 32;
uint32 c : 32;
}


Now using this code:


uint8 rawData[9] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFF, 0xFF};
MyBitField \*pMyBitField = (MyBitField\*)rawData;


I expect(on little endian 32bit CPU):

the a's field of the pMyBitField to be 0x12,

the b's field of the pMyBitField to be 0x9A785634,

the a's field of the pMyBitField to be 0xFFFFDEBC.


The compiler choose to make some unexplained alignment.

I know that in case you use different types inside the bit filed you might get alignment, but this is not the case.

How can i do it?


Let's focused on Visual Studio 2005 but any other env support will be blessed as well.


*I read some post of packing but it did not change the alignment problem.


Thanks!

Answer

I'd expect your code not to compile. rawData has an array type; this implicitly converts to a pointer, but cannot be converted to a class type, implicitly or explicitly.

For the rest, how the compiler lays out bit fields is implementation defined, but in your case, I'd expect it to be irrelevant; on a 32 bit machine, a 32 bit bitfield will normally force the compiler to use the next word, so only the first bit field has any effect. Depending on the compiler, it will cause the compiler to put the value on either the high order 8 bits, or the low order 8 bits (and leave the rest of the word undefined).

If you need to match an external format, the only way of doing this reliably is byte by byte, inserting whatever value is necessary for that byte.

Comments