I'm looking for a way to determine the size of an unnamed struct because I want to explicitly calculate padding.
I have set of structures that have a common a general layout
struct Packet {
uint8_t AllocatorDebugInfo[ALLOC_SIZE /* constant across all structs */ ];
/* OPTIONAL */ uint8_t Padding[ /* Needs to be determined */ ];
uint8_t Header[HEADER_SIZE /* dependent on packet type */ ];
uint8_t Payload[PAYLOAD_SIZE /* constant across all structs*/ ];
};
I have the following requirements:
I'm trying to calculate the Header Size as shown in the code below:
typedef union {
struct { /* opaque */ } SmallHeader;
struct { /* opaque */ } MedHeader;
struct { /* opaque */ } LargeHeader;
} HeaderSizes;
HeaderSizes *p;
enum { SMALL_PADDING = sizeof(HeaderSizes) - sizeof(p->SmallHeader)) };
Unfortunately memory is tight and I'm looking ways to avoid the global pointer.
Apparently trying to calculate an optional padding like this is a very bad idea. This only works as long as you are aware of the fact, that the biggest struct will have more padding than expected (zero).
enum { LARGE_PADDING = sizeof (HeaderSizes) - sizeof ((HeaderSizes*)0->LargeHeader) };
struct LargePacket {
uint8_t AllocDebug[ALLOC_SIZE];
uint8_t Padding[ LARGE_PADDING ]; /* will evaluate to 0 -- struct size 1 */
uint8_t Payload[ PAYLOAD_SIZE ]; /* off by 1 */
};
The size of a structure is greater than the sum of its parts because of what is called packing. A particular processor has a preferred data size that it works with. Most modern processors' preferred size if 32-bits (4 bytes).
Anonymous unions/structures are also known as unnamed unions/structures as they don't have names. Since there is no names, direct objects(or variables) of them are not created and we use them in nested structure or unions. Definition is just like that of a normal union just without a name or tag.
Processor doesn't read 1byte at a time from memory.It reads 1 word at a time. In 32 bit processor, it can access 4 bytes at a time which means word size is 4 bytes. Similarly in a 64 bit processor, it can access 8 bytes at a time which means word size is 8 bytes.
The sizeof for a struct is not always equal to the sum of sizeof of each individual member. This is because of the padding added by the compiler to avoid alignment issues. Padding is only added when a structure member is followed by a member with a larger size or at the end of the structure.
The sizeof
operator doesn't need a valid instance to return the size. It just needs an expression that evaluates to the correct type. While it's a bit of a hack, you could cast NULL
to HeaderSizes*
.
sizeof(((HeaderSizes*)NULL)->SmallHeader)
Since this isn't dereferencing a null pointer, but is a syntactic construct, the above is perfectly valid and gives a correct result. Such as in the bellow example.
http://ideone.com/QKTOdP
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