Почему существует несоответствие размеров между структурами и объединениями?

Я объявил объединение, распределяющее 4100 байтов переменной "sample_union", и сделал одно и то же объявление объединения как часть структуры, которая выделяет 4104 байта.

union test_size_union {
    struct {
        uint8_t type;
        union {
            uint8_t count;
            uint8_t list;
        };
        uint16_t rc;
        uint16_t arr_value[2048];
    };
    uint64_t first_dword;
}__attribute__((packed)) sample_union ;

Размещение вышеуказанного объединения внутри структуры выделяет 4104 байта.

struct test_size_struct {
    union {
        struct {
            uint8_t type;
            union {
                uint8_t count;
                uint8_t list;
            };
            uint16_t rc;
            uint16_t arr_value[2048];
        };
        uint64_t first_dword;
    };
}__attribute__((packed)) sample_struct;

Ну, это не требование к проекту, но я хотел бы знать, почему компилятор ведет себя по-другому для этого двух объявлений.

Версия gcc: (GCC) 4.9.2, x86_64

Платформа: Linux, x86_64

Ответ 1

Когда вы разместили объединение внутри структуры, вы не отметили объединение как packed. В распакованном объединении есть небольшое дополнение (четыре байта), чтобы его размер был кратным размеру uint64_t.

Упакованный союз не имеет этого дополнения, поэтому он меньше.

Как побочное наблюдение, анонимная структура внутри объединения не помечена packed. В этом случае это не имеет значения, потому что все хорошо выровнено в любом случае, но это то, о чем нужно знать.