-6

Consider this program:

#include "stdio.h"
#include "conio.h"

void  main() {
    struct ax {
        char name[5]; //5 bytes
        union {
            float y; // 4 bytes
            int z;   // 4 bytes
        } u; // sizeof this union should be 4
    } t; //hence 4 + 5 should be 9

    printf("%d",(int)sizeof(t));

    getch();
}

Why does it print 12?

John Bollinger
  • 160,171
  • 8
  • 81
  • 157

3 Answers3

4

The simple answer is that the structure contains padding, making its size (as reported by sizeof) greater than the sum of its parts. The padding between structure members typically exists to align each structure member (e.g., to a 32- or 64-bit boundary). There may also be padding at the end, e.g., to make multiple consecutive structures (such as in an array) aligned.

Relevant parts from the C11 standard:

6.7.2.1 (Semantics of structures and unions)

  1. … There may be unnamed padding within a structure object, but not at its beginning.

6.5.3.4 (sizeof)

  1. … When applied to an operand that has structure or union type, the result is the total number of bytes in such an object, including internal and trailing padding.
Arkku
  • 41,011
  • 10
  • 62
  • 84
2

The most likely layout on a 32 bit machine is: 5 byte char + 3 byte padding + 4 byte union = 12 bytes.

You can see the memory layout for yourself:

#include <stddef.h>
#include <stdio.h>

printf("%zu\n", offsetof(struct ax, u)); // likely prints 8
Lundin
  • 195,001
  • 40
  • 254
  • 396
0

Look for Data Alignment. The union was aligned to the next 32-bit (or 64-bit) address, (anyway) 8 bytes after the start of the char[5].

Debugging an instance (and looking at its memory layout) will show you how the char[5] was actually "padded" with 3 extra bytes.

uv_
  • 746
  • 2
  • 13
  • 25
  • 1
    Whereas that's a plausible and even likely explanation, it is not certain to be correct. C implementations have latitude to layout the structure differently, and some might have reason to do so, too. Furthermore, implementations are free insert padding after any member for any reason. Alignment is the usual purpose of such padding, but it does not *have* to be the purpose. – John Bollinger Dec 14 '18 at 14:48