What is a "packed" structure in C?

49,500

Solution 1

When structures are defined, the compiler is allowed to add paddings (spaces without actual data) so that members fall in address boundaries that are easier to access for the CPU.

For example, on a 32-bit CPU, 32-bit members should start at addresses that are multiple of 4 bytes in order to be efficiently accessed (read and written). The following structure definition adds a 16-bit padding between both members, so that the second member falls in a proper address boundary:

struct S {
    int16_t member1;
    int32_t member2;
};

The structure in memory of the above structure in a 32-bit architecture is (~ = padding):

+---------+---------+
| m1 |~~~~|   m2    |
+---------+---------+

When a structure is packed, these paddings are not inserted. The compiler has to generate more code (which runs slower) to extract the non-aligned data members, and also to write to them.

The same structure, when packed, will appear in memory as something like:

+---------+---------+
| m1 |   m2    |~~~~
+---------+---------+

Solution 2

It instructs the compiler to not add any padding between members of the struct.

See, for example, this page.

Solution 3

Let me explain the concept of padding in structures and then packed structures by taking an example.

And then let us see why packing is required.

Padding:

struct eg_struct
{
           unsigned char abc;
           unsigned int  xyz;
}

When the structure is declared as above on a 16 bit architecture, the variable abc would be assigned some address. The next address is not assigned to variable xyz, instead one extra byte is added, and then the next address would be assigned to the variable xyz.

In the end, the structure looks something like below:

struct eg_struct
{
           unsigned char abc;
           unsigned char paddedbytes[1];
           unsigned int  xyz;
}

Padding makes addresses of member variables easily accessible to the microcontroller. The disadvantage is extra unnecessary bytes that come into the picture.

Packing:

If same structure is declared using the attribute “packed”, the extra byte will not be added after the variable abc.

Let me give one example where packing is needed:

Consider a microcontroller interfaced with an EEPROM where some structure is being stored.

Imagine a function writing to the EEPROM would look as below:

Write_EEPROM(EEPROM address, Ram address, Byte count);

Now if packing is not done, the extra padded bytes would occupy space in the EEPROM, which is of no use.

Solution 4

_attribute__((__packed__)) means (most probably) "do not insert any padding to make things faster" and may also mean "do not insert any alignments to preserve alignment".

Solution 5

One thing that has not been explicitly called out is that packing usually is done to match predefined field structures. For example, at the low level layer of a network interface, a series of bytes is exchanged between networked machines. After the data is received, it will need to be mapped to a high level structure so that the data can be manipulated easily. This is when no-padding is usually necessary, so that the structure directly maps to the bytes.

Network data interchange also involves byte endianness issue (i.e. almost all network data uses big endian format regardless the endianness of the source and destination machines).

Furthermore, some machines cannot access wide data in non-aligned address, for example, Cortex-M0 cores cannot access 32-bit data in non-32-bit aligned address, so care must be taken on writing networking code in such cases.

Share:
49,500
PICyourBrain
Author by

PICyourBrain

Electrical Engineer, Software Developer, Tinkerer

Updated on May 01, 2020

Comments

  • PICyourBrain
    PICyourBrain about 4 years

    I am going though some C code written for the Microchip C30 compiler and I often see structs defined as follows:

    typedef struct __attribute__((__packed__)) 
    {
        IP_ADDR     MyIPAddr;               // IP address
        IP_ADDR     MyMask;                 // Subnet mask
        IP_ADDR     MyGateway;              // Default Gateway
            // etc...
    } APP_CONFIG;
    

    What does packed mean?

  • flolo
    flolo about 13 years
    I guess you mean the opposite - packed means to omit any padding and not to add it.
  • Kev
    Kev over 12 years
    The link in this answer is broken, any chance of fixing?
  • chux - Reinstate Monica
    chux - Reinstate Monica almost 8 years
    Detail: "not add any padding between members" is more like to add minimum packing. Certain architectures may still oblige some padding in select cases. (e.g. int must be on even address boundary to prevent bus fault.)
  • damned
    damned over 6 years
    Tangential question but why would one create a packed structure if it makes things slower? Is it to reduce memory footprint?
  • jjmontes
    jjmontes about 6 years
    One use case: they are used very often for defining and implementing network protocols, binary formats... You usually don't want to add paddings to structures that are going to be stored or sent over the network.
  • Jumpman
    Jumpman over 5 years
    Considering your example, 16 bits + 32 bits = 48 bits = 12 bytes and that is indeed a multiple of 4 bytes. Why would a compiler then apply padding?
  • Juliano
    Juliano over 5 years
    @Maxitj, 48 bits are 6 bytes, not 12.
  • Jumpman
    Jumpman over 5 years
    @Juliano silly me, was rly tired while I was reading this post :)
  • Babajan
    Babajan about 5 years
    @laurenz albe Thanks for making my answer more presentable.