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
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?
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.
Bit field storage is implementation dependent. The fields that you have defined may be padded (increasing the storage required).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With