0
#include <stdio.h>
#include <stdint.h>

typedef struct s{
    uint8_t a[1];
    uint16_t b;
    uint8_t c[1];
}s_t;

int main()
{
    printf("size = %d", sizeof(s_t));
    return 0;
}

I am not sure why the output of this program is 6 bytes and not 5. Why does the compiler pad an extra byte after the last member ? It also seems like, if you make the last member array length 3, the padding makes the size 8. I am unable to explain this since this is not the case for 2 arrays only.

too honest for this site
  • 12,050
  • 4
  • 30
  • 52
marc
  • 797
  • 1
  • 9
  • 26

1 Answers1

0

Here is an illustration of the alignment that the compiler generates:
Bytes:

+-----+---------------+  
|  0  | a[1]          |  
+-----+---------------+  
|  1  | N/A (padding) |  
+-----+---------------+  
|  2  | b             |  
+-----+---------------+  
|  3  | b             |  
+-----+---------------+  
|  4  |    c          |  
+-----+---------------+  

As 16-bit quantities:

+---+------+----+  
| 0 | a[i] |    |  
+---+------+----+  
| 2 | b         |
+---+------+----+  
| 4 |   c  |    |
+---+------+----+  

Processors like to fetch 16-bit quantities from even addresses.
When they are on odd addresses, the computer may have to make 2 16-bit fetches, and extract the unaligned data out of them.

The easy method to eliminate this extra fetch is to add padding bytes so that 16-bit quantities align to even addresses.

A rule of thumb is to place the larger items first, then the smaller. Applying this rule:

+---+------+  
| 0 | b    |  
+---+------+  
| 2 | a[1] |  
+---+------+  
| 3 | c    |  
+---+------+  

The rule eliminates the need for an extra padding byte.

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154