Electronic – Usage of the #pragma pack(1) compiler directive on embedded applications

ccompilerembeddedmicrocontroller

I have recently come across this #pragma pack(1) preprocessor directive and was wondering why it is being used?

I Googled the usage, and found it has other options such as push,pop etc. Has anyone used this on their embedded application?

I would like to know some examples of how/why you have used this directive and on what kind of processor? What are the pro's/con's of using this directive?

Thanks.

Best Answer

#pragma pack(1) ensures that C struct items are packed in order and on byte boundaries. It may save RAM - which is often precious in a microcontroller.

Packed structs also allow for casting directly over memory buffers for data interchange:

void f(void *buf)
{
  struct ip_header *hdr = (struct ip_header *)buf;
  hdr->dst = 0x8000001;
}

Be careful where you use #pragma pack. It's globally scoped (as it's in the preprocessor), so forgetting to turn it off will affect any #include files. If you only mean to pack certain structs, consider using GCC's __attribute__ ((packed)).

However, due to alignment issues, packed structs can impact performance. For example:

When packed into bytes:

struct
{
  uint8_t  a;
  uint32_t b;
  uint8_t  c;
  uint8_t  d:
};

Will be stored as (not accounting for endianness):

a, b0, b1, b2, b3, c, d

However, many architectures require 32bit accesses to be aligned to 32bit addresses. With the packed struct, the machine will have to make several byte accesses then stich them together again.

Faced with the above struct without packing enabled, the compiler could reorganise it as:

b0, b1, b2, b3, a, c, d