When do structures not have padding?

The predominant use of padding is to align structure members as required by the hardware (or other aspects of the C implementation). An algorithm for laying out data in a struct is in this answer.

To answer the question in your title, when do structures not have padding: A structure does not require padding for alignment if each member’s alignment requirement is a divisor of the total size of all preceding members and of the total size of all members. (A C implementation may still add padding for reasons other than alignment, but that is a bit unusual.)

For your examples, let’s suppose, in a C implementation, short is two bytes in size and requires two-byte alignment. By definition, char is one byte and requires one-byte alignment.

Then, in struct s {short c;}:

  • c is put at the beginning of the struct. There is never any padding at the beginning.
  • If we make an array of these struct, the next struct s will begin two bytes beyond the first, and its member c will still be at a multiple of two bytes, so it is aligned correctly.
  • Therefore, we do not need any padding to make this work.

In contrast, in struct s {short c; char a;}:

  • c is put at the beginning.
  • a is put two bytes after c. This is fine, since a only requires one-byte alignment.
  • If we do not add any padding, the size of the struct is three bytes. Then, if we make an array of these struct, the next struct s will begin three bytes from the start.
  • In that second struct s, the c member will be at an offset of three bytes. That violates the alignment requirement for short.
  • Therefore, to make this struct work, we must add one byte of padding. This makes the total size four bytes. Then, in an array of these struct, all the members will be at boundaries required by their alignment.

Even if you declare just a single object of a structure, as in struct s {short c; char a;} x;, a structure is always laid out so it can be used in an array.


The first structure has one element of size 2 (assuming short has size 2 on your system). It is as good as directly having an array of short directly.

The second structure is a special thing: access to short variables is best done on even addresses. If we hadn't padding, we had the following:

struct s arr[5]; // an array
void * a = arr; // needed to reference it

Then,

  • arr[0].c is at a.
  • arr[0].a is at a + 2 bytes.
  • arr[1].c is at a + 3 bytes (!).
  • arr[1].a is at a + 5 bytes (!).

As it is preferrable to have arr[1].c at an even address, we add padding. Then,

  • arr[1].c is at a + 4 bytes.
  • arr[1].a is at a + 6 bytes.

Tags:

C