scalauser scalauser - 4 years ago 132
C Question

Is it necessary to use Data structure alignment

I'm reading this code for a 32 bit MCU.

My question is - is it necessary to use

__attribute__((packed, aligned(1)))
? Is this just good practice or does it cause unpredictable behavior without it.

typedef struct __attribute__((packed, aligned(1))) radio_packet {
uint8_t tag; /* 1 byte */
uint32_t id; /* 4 bytes */
uint16_t size; /* 2 bytes */
uint16_t element; /* 2 bytes */
uint8_t length; /* 1 byte */
// The items above comprise HDR_SIZ
uint8_t data[PKT_SIZ];

} radio_packet_t;

Answer Source

Is this just good practice or does it cause unpredictable behavior without it?

None of the two. If the data, being packed or not, only are used inside the program, then it is good to let the compiler choose how to order this data and how to align them - unless you really want to save ram.

If the data must have a particular format - and I think yes, because your structure is named "radio_packet", then you want to be sure that the format you write is respected. In this case you want to pack the data, and insert manually the padding if requested by the format.

In this particular case the name of the struct make me think that a packet will be transmitted to some other equipment, which will run software written perhaps with a different compiler. So, you don't want that the compiler interferes with the order and position of your fields. In other words, the structure is not used only inside the program.

To extend further. It is good practice not to use packing and/or aligning, in normal situations, because the compiler knows better than a human what is best. You use packing/aligning when you know what to do better than the compiler, for example because you have to respect some format the compiler is not aware of. Normally (but depends on the compiler), it makes choices to optimize performances, perhaps wasting some ram. In order to achieve maximum performance it can align fields to the preferred alignment of the CPU, inserting unused/hidden fields or even reordering them. This is not good if you then take that packet and send it to some hardware or software which doesn't use the same padding/alignment: a 32 bit CPU prefers 32-bit aligned data, but a 8 bit CPU does not care.

From the point of view of your program/CPU, there will never be unpredictable behavior, in either case. The compiler knows very well what it is doing, even when you impose to it some restrictions. The wrong or [probably not so] unpredictable behavior happens when the data, misformatted, enters/exits your program.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download