-2

Following is my code

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

union myUnion {
    struct {
        uint8_t a1;
        uint8_t b1;
        uint8_t c1;
        uint8_t d1;
        uint8_t e1;
    } abc;
    int a;
};

int main() {

    printf("size:%ld\n", sizeof(union myUnion));

    return 0;
}

Output:

size:8

Here why size of union is 8, stuct has 5 member total 5byte and int a 4byte hence size should be 9 correct, why size returns 8 ?

Trying to undersatand how memory allocation happend

Allan Wind
  • 23,068
  • 5
  • 28
  • 38

2 Answers2

2

The structure has five one-byte members, so it needs five bytes. The int probably needs four bytes. So the union needs the greater of these, five bytes.

However, every object’s size must be a multiple of its alignment requirement, so that, if we make an array of them, each element of the array starts at its required alignment. The int probably has an alignment requirement of four bytes. It is in the union, so the union must have an alignment requirement of at least four bytes.

So the size of the union must be a multiple of four bytes. Five bytes is not a multiple of four bytes. So, to make the union’s size a multiple of four bytes, the compiler added three otherwise unused bytes, called padding, to make the size eight bytes, which is the next multiple of four bytes.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • `So the size of the union must be a multiple of [the size of int, which in this case is] four bytes`. This can be nicely demonstrated by changing `a`'s type to `int16_t`, which makes the union size go to 6 for gcc or clang: https://godbolt.org/z/Kd9hPTfn7 – Elliott Apr 13 '23 at 04:29
1

The C compiler padded your union. See 6.7.2.1, paragraph 18 and 19:

The size of a union is sufficient to contain the largest of its members. The value of at most one of the members can be stored in a union object at any time. A pointer to a union object, suitably converted, points to each of its members (or if a member is a bit-field, then to the unit in which it resides), and vice versa. The members of a union object overlap in such a way that pointers to them when converted to pointers to character type point to the same byte. There may be unnamed padding at the end of a union object, but not at its beginning.

There may be unnamed padding at the end of a structure or union.

gcc (and others) support extensions for type attributes. You may be particular interested the packed attribute:

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

union myUnion {
    struct {
        uint8_t a1;
        uint8_t b1;
        uint8_t c1;
        uint8_t d1;
        uint8_t e1;
    } abc;
    int a;
} __attribute__((packed));

int main() {
    printf("size:%ld\n", sizeof(union myUnion));
    return 0;
}

and it will now return:

size:5
Allan Wind
  • 23,068
  • 5
  • 28
  • 38
  • How does this answer the question? What does “The C compiler passed your union” mean? Why did the compiler pad the union? – Eric Postpischil Apr 13 '23 at 02:28
  • @EricPostpischil Op asks how and the answer is the compiler adds padding. Heh... fixing my typo might make that more sense. – Allan Wind Apr 13 '23 at 03:45