user2485865
user2485865

Reputation:

Output of Structure Size having bitfield

#include<stdio.h>
static struct s
{

    unsigned a:5;
    unsigned b:5;
    unsigned c:5;    
    unsigned d:5;

}v={1,2,3,4};

int main()
{
    printf("size of v = %d\n",sizeof(v));
}

"Answer is 4". I can't explain this output.

#include<stdio.h>
static struct s
{

    unsigned a:5;
    unsigned b:5;

}v={1,2};

int main()
{
    printf("size of v = %d\n",sizeof(v));
}

"Answer is still 4" .. how is bit field affecting the Structure Size ??

Upvotes: 2

Views: 523

Answers (4)

Bryan Olivier
Bryan Olivier

Reputation: 5307

If you would have used unsigned char as type of the bit fields you would have gotten size 4 and size 2 resp. The alignment, and thus size, of the struct is usually determined by the integral type of the bitfields. Packing of structures, especially with bit-fields, is highly implementation defined, but dictated by 6.7.2.1 ad 11

An implementation may allocate any addressable storage unit large enough to hold a bit-field. If enough space remains, a bit-field that immediately follows another bit-field in a 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 order of allocation of bit-fields within a unit (high-order to low-order or low-order to high-order) is implementation-defined. The alignment of the addressable storage unit is unspecified.

Most compilers use the integral type given with the bit-field as the 'addressable storage unit'.

Note also that structure packing is often specified as part of the Application Binary Interface (ABI) of an architecture, to ensure interoperability of compilers for this architecture.

Elaborating more on your examples, assuming the GCC compiler for the x86 architecture.

struct
{       unsigned int a:5;
        unsigned int b:5;
        unsigned int c:5;
        unsigned int d:5;
};

The four bit-fields are located in the first 20 bits of a 32 bit container.

struct
{       unsigned char a:5;
        unsigned char b:5;
        unsigned char c:5;
        unsigned char d:5;
};

Each bit-field is located in its own 8 bit container, so again 32 bits.

struct
{       unsigned int a:5;
        unsigned int b:5;
};

The bit-fields are located in the first 10 bits of a 32-bit container, so the whole struct is still 32 bit.

struct
{       unsigned char a:5;
        unsigned char b:5;
};

Both bit-fields are located each in their own 8-bit container, so the whole struct is 16 bit.

struct
{       unsigned char a:5;
        unsigned char b:3;
        unsigned char c:3;
        unsigned char d:5;
        unsigned char e:5;
};

Bit-fields a and b are in an 8-bit container. Bit-fields c and d are in an 8-bit container and bit-field e is in an 8-bit container, making 24 bits in total.

Upvotes: 2

Guillaume Ballet
Guillaume Ballet

Reputation: 311

By default, gcc aligns data on a byte boundary, and on some platforms (especially RISC) on a machine-word boundary. This is because non-byte-aligned reads will (on RISC machines) cause an exception, thus slowing the program. That's why every field is stored in their own byte, even if they are only 5 bit long. For proper packing, use __attribute__((packed)):

#include<stdio.h>

static struct s
{
    unsigned a:5 __attribute__((packed));
    unsigned b:5 __attribute__((packed));
}v={1,2};

int main()
{
    printf("size of v = %d\n",sizeof(v));
}

The output of this is:

size of v = 2

which is expected as you have 10 bytes total, the size is rounded up to the next byte.

Upvotes: 4

Ed Heal
Ed Heal

Reputation: 59987

Simple because the processor likes 4 (AKA data alignment)

Upvotes: 1

bazza
bazza

Reputation: 8394

The C compiler is using a single unsigned int as storage for the bit field. And because the unsigned int is 4 bytes long the structures size is inevitably 4 bytes too.

Upvotes: 0

Related Questions