This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: sizeof bit-fields
- From: Eljay Love-Jensen <eljay at adobe dot com>
- To: Massimiliano Cialdi <cialdi at firenze dot net>, gcc help <gcc-help at gcc dot gnu dot org>
- Date: Thu, 16 Oct 2003 07:25:26 -0500
- Subject: Re: sizeof bit-fields
Hi Massimiliano,
>How can I obtain a 5 bytes long structure (if it is possible)?
The bit-fields are going to pack like this in memory (probably), big-endian representation on a 32-bit/word machine:
+--3---------2---------1---------+
0 +..ccccccccccbbbbbbbbbbaaaaaaaaaa+
4 +......................dddddddddd+
+--------------------------------+
So the 32-bit word at offset 0 has a, b, and c and 2 fallow bits. The 32-bit word at offset 4 has d and 22 fallow bits.
Note that bit-fields (typically) do not span across words.
If you really want the structure to be 5 bytes AND have byte alignment, you'll have to do more of the work yourself. For example, in C++, I'd do it this way:
typedef char byte;
struct rec
{
byte m[5]; // 40-bits to pack our 4 10-bit unsigned values.
void setA(unsigned i_10);
void setB(unsigned i_10);
void setC(unsigned i_10);
void setD(unsigned i_10);
void setE(unsigned i_10);
unsigned getA() const;
unsigned getB() const;
unsigned getC() const;
unsigned getD() const;
unsigned getE() const;
};
void rec::setA(unsigned i_10)
{
m[0] = i_10 & 0xFF;
m[1] = (m[1] & 0xFC) | ((i_10 >> 8) & 0x03);
}
unsigned rec::getA() const
{
return (m[1] & 0x03) | (m[0] & 0xFF);
}
I leave get/set B, C, D as an exercise. Note that the compiler's optimizer will optimize the seemingly superfluous masking where it's unnecessary, which makes this stuff fairly platform agnostic.
Another advantage is that you can read/write this structure directly to file or over a socket, on any 8-bit/byte platform, and it'll work.
HTH,
--Eljay