Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

size of a structure containing bit fields [duplicate]

Possible Duplicate:
Why isn't sizeof for a struct equal to the sum of sizeof of each member?

I was trying to understand the concept of bit fields. But I am not able to find why the size of the following structure in CASE III is coming out as 8 bytes.

CASE I:

struct B    
{
    unsigned char c;  // +8 bits
} b;

sizeof(b); // Output: 1 (because unsigned char takes 1 byte on my system)

CASE II:

struct B
{
    unsigned b: 1;
} b;

 sizeof(b); // Output: 4 (because unsigned takes 4 bytes on my system)

CASE III:

struct B
{
    unsigned char c;  // +8 bits
    unsigned b: 1;    // +1 bit
} b;

sizeof(b); // Output: 8 

I don't understand why the output for case III comes as 8. I was expecting 1(char) + 4(unsigned) = 5.

like image 693
user1367292 Avatar asked Oct 06 '12 17:10

user1367292


2 Answers

You can check the layout of the struct by using offsetof, but it will be something along the lines of:

struct B
{
    unsigned char c;  // +8 bits
    unsigned char pad[3]; //padding
    unsigned int bint; //your b:1 will be the first byte of this one
} b;

Now, it is obvious that (in a 32-bit arch.) the sizeof(b) will be 8, isn't it?

The question is, why 3 bytes of padding, and not more or less?

The answer is that the offset of a field into a struct has the same alignment requirements as the type of the field itself. In your architecture, integers are 4-byte-aligned, so offsetof(b, bint) must be multiple of 4. It cannot be 0, because there is the c before, so it will be 4. If field bint starts at offset 4 and is 4 bytes long, then the size of the struct is 8.

Another way to look at it is that the alignment requirement of a struct is the biggest of any of its fields, so this B will be 4-byte-aligned (as it is your bit field). But the size of a type must be a multiple of the alignment, 4 is not enough, so it will be 8.

like image 158
rodrigo Avatar answered Sep 30 '22 16:09

rodrigo


I think you're seeing an alignment effect here.

Many architectures require integers to be stored at addresses in memory that are multiple of the word size.

This is why the char in your third struct is being padded with three more bytes, so that the following unsigned integer starts at an address that is a multiple of the word size.

like image 27
rodion Avatar answered Sep 30 '22 17:09

rodion