Size of bit-field struct in C

I have a representation of an IP header in C with bit-precision fields:

typedef struct __attribute__((packed)) {
    unsigned char __reserved : 1;
    unsigned char dont_fragment : 1;
    unsigned char more_fragment : 1;
    unsigned short fragment_offset : 13; // if fragmented, in 8 byte units from the start of the datagram
} ipv4_fragmenting;

I use 16 bits that can be stored on 2 bytes. So why is the size of the structure (sizeof(ipv4_fragmenting)) is 4 instead of 2?

My compiler: GCC 4.8.1

Edit:

If bitfields are so platform-specific and packed attribute is unreliable what would be the correct solution to represent elements of previously defined protocols like IPv4?

Upvotes: 3

Views: 3297

Answers (4)

Javier
Javier

Reputation: 831

I've always read that type sizes depends on the implementation and architecture and the OS. I don't think it's a bug. Anyway, you must trust on your sizeof function, as this will tell you your particular truth.

Upvotes: 0

legends2k
legends2k

Reputation: 33004

Like I've already commented, speculating on bit field and structure size is moot since the language doesn't mandate anything in this area.

As for the size being 4 on GCC 4.8.1 (assuming a 32-bit compiler); this is perhaps a bug on GCC 4.8.1. I've raised a question on SO previously where setting the packed attribute doesn't work as expected, like here. For a byte aligned packing only using #pragma pack works. Example:

#include <stdio.h>

#pragma pack(push, 1)
typedef struct {
    unsigned char __reserved : 1;
    unsigned char dont_fragment : 1;
    unsigned char more_fragment : 1;
    unsigned short fragment_offset : 13; // if fragmented, in 8 byte units from the start of the datagram
} ipv4_fragmenting;
#pragma pack(pop)

int main()
{
    printf("%u\n", sizeof(ipv4_fragmenting));
}

This prints 3 for me, as expected on a ILP32 machine MinGW GCC 4.8.1.

Upvotes: 2

AnthonyLambert
AnthonyLambert

Reputation: 8840

On some 32bit platforms structures are padded to be on 32 bit boundaries, eg. every 4 bytes. On GCC I think you can control this on some platforms see: Structure Packing Pragmas

Upvotes: 0

bblincoe
bblincoe

Reputation: 2483

Bit field storage is implementation dependent. The fields that you have defined may be padded (increasing the storage required).

Upvotes: 1

Related Questions