scalauser
scalauser

Reputation: 449

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;

Upvotes: 4

Views: 354

Answers (2)

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.

Upvotes: 3

Serve Laurijssen
Serve Laurijssen

Reputation: 9733

It is not necessary but you can make assumptions in the code later on. You can do safe memcpy from char arrays to radio_packet_t for instance and not all components in the program need to know the type radio_packet_t and can just use byte buffers for sending radio_packet_t over the networkd or in a file or whatever.

Upvotes: 0

Related Questions