Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sizeof union larger than expected. How does type alignment take place here?

#include <stdio.h>

union u1 {
    struct {
        int *i;
    } s1;
    struct {
        int i, j;
    } s2;
};

union u2 {
    struct {
        int *i, j;
    } s1;
    struct {
        int i, j;
    } s2;
};

int main(void) {
    printf("        size of int: %zu\n", sizeof(int));
    printf("size of int pointer: %zu\n", sizeof(int *));
    printf("   size of union u1: %zu\n", sizeof(union u1));
    printf("   size of union u2: %zu\n", sizeof(union u2));
    return 0;
}

Results in:

$ gcc -O -Wall -Wextra -pedantic -std=c99 -o test test.c
$ ./test
        size of int: 4
size of int pointer: 8
   size of union u1: 8
   size of union u2: 16

Why does adding an integer of 4 bytes to nested struct s1 of union u2 increase the size of the union as a whole by 8 bytes?

like image 994
Will Avatar asked Dec 10 '11 02:12

Will


People also ask

Why does the sizeof operator return a size larger for a structure than the total sizes of the structure's members?

The sizeof for a struct is not always equal to the sum of sizeof of each individual member. This is because of the padding added by the compiler to avoid alignment issues. Padding is only added when a structure member is followed by a member with a larger size or at the end of the structure.

What is the sizeof union?

Union is special data type used in C programming it allows to store different data types in the same memory location. All the element of union share the common memory and union size is biggest element size. Therefore the output of the program or size of union definition is 4.

How is the size of structure determined?

The size of a structure is greater than the sum of its parts because of what is called packing. A particular processor has a preferred data size that it works with. Most modern processors' preferred size if 32-bits (4 bytes).

What is the size of union below in a 32 bit system?

It's usually 4 for 32-bit machine, and 8 for 64-bit machine.


1 Answers

The struct u2.s2 is 16 bytes because of alignment constraints. The compiler is guaranteeing that if you make an array of such structs, each pointer will be aligned on an 8-byte boundary. The field *i takes 8 bytes, then j takes 4 bytes, and the compiler inserts 4 bytes of padding. Because the struct is 16 bytes, the union containing it is also 16 bytes.

like image 113
Norman Ramsey Avatar answered Oct 07 '22 20:10

Norman Ramsey