Compilers typically insert trailing padding on structures to satisfy alignment restrictions when they are used in arrays:
// Size 4, alignment 2
struct A {
uint16_t x;
uint8_t y;
// Padding 1 byte
};
// Size 6, alignment 2
struct B {
struct A xy;
uint8_t z;
// Padding 1 byte
};
Now consider combination of these using internal structure:
struct AB {
struct {
uint16_t x;
uint8_t y;
} xy;
uint8_t z;
};
Following could fit in 4 bytes, while not breaking alignment restrictions.
Also, internal structure xy
has no type which could be used elsewhere, so
trailing padding for it isn't needed.
Downside is that member xy
would be incompatible with struct A
, but there
is no reason why it should be as they are in different type definitions.
Is compiler allowed to do this size optimization?
Or, to put it other way, does standard require that 2 structures with equal members will always result in equal layout?
In order to align the data in memory, one or more empty bytes (addresses) are inserted (or left empty) between memory addresses which are allocated for other structure members while memory allocation. This concept is called structure padding.
In Structure, sometimes the size of the structure is more than the size of all structures members because of structure padding. Note: But what actual size of all structure member is 13 Bytes. So here total 3 bytes are wasted. So, to avoid structure padding we can use pragma pack as well as an attribute.
Padding and packing are just two aspects of the same thing: packing or alignment is the size to which each member is rounded off. padding is the extra space added to match the alignment.
Structure padding is a concept in C that adds the one or more empty bytes between the memory addresses to align the data in memory.
The answer is likely given by the notion of compatible types. If t1
and t2
are compatible types, a pointer to t1
can be used to access memory that was set using type t2
.
In the C11 standard:
6.2.7 Compatible type and composite type
- … Moreover, two structure, union, or enumerated types declared in separate translation units are compatible if their tags and members satisfy the following requirements: If one is declared with a tag, the other shall be declared with the same tag. If both are completed anywhere within their respective translation units, then the following additional requirements apply: there shall be a one-to-one correspondence between their members such that each pair of corresponding members are declared with compatible types; if one member of the pair is declared with an alignment specifier, the other is declared with an equivalent alignment specifier; and if one member of the pair is declared with a name, the other is declared with the same name. …
Two structs that do not have the same tag are not compatible types, and I do not see anything that force them to have the same layout.
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