How we can avoid structure padding in C apart from using pragma pack aur bit field? Is there any other method available?
Pack the biggest items at the start of the structure. Pack smaller items towards the end.
struct optimal_packing
{
double d;
int i[4];
short j[3];
char s[24];
};
To be slightly more accurate, it is the items with the most stringent alignment requirements that need to come earliest (which tend to be pointers and double
or perhaps long double
), and those with less stringent alignment requirements at the end (short
and char
). You can still end up with tail padding if the total length of the components adds up to, say 35 bytes, but one of the types requires an 8-byte alignment; there'd be 5 bytes of padding.
The only completely portable and reliable way to avoid structure padding is not to use real members in your struct
at all. Use a single char
array member, and define macros that access its contents:
struct paddingless {
// char *p;
// double d;
// char c;
#define OFFSET_P 0
#define OFFSET_D (OFFSET_P + sizeof(char *))
#define OFFSET_C (OFFSET_D + sizeof(double))
#define OFFSET_END (OFFSET_C + sizeof(char))
char data[OFFSET_END];
};
Portable getters and setters would look like this:
inline double paddingless_get_d(const struct paddingless *o) {
double val;
memcpy(&val, o->data + OFFSET_D, sizeof(val));
return val;
}
inline void paddingless_set_d(struct paddingless *o, double val) {
memcpy(o->data + OFFSET_D, &val, sizeof(val));
}
If you know that your architecture accepts unaligned access, you can get away with a setter being defined with a cast:
#define paddingless_get_d(o) (*(double *) ((o)->data + OFFSET_D))
#define paddingless_set_d(o, val) (*(double *) ((o)->data + OFFSET_D) = (val))
This is non-portable, but potentially faster than the alternative. And it works on a vax x86...
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