Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is there a size mismatch between structures and unions?

Tags:

c++

c

linux

gcc

I have declared a union allocating 4100 bytes to variable "sample_union" and made the same union declaration as part of a structure which is allocating 4104 bytes.

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 ;

Placing the above union inside structure is allocating 4104 bytes.

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;

Well, this is not a project requirement, but I would like to know why compiler is behaving differently for this two declaration.

gcc version: (GCC) 4.9.2, x86_64

Platform: Linux, x86_64

like image 420
user50 Avatar asked Apr 14 '16 10:04

user50


People also ask

Why is the size of a union greater than its members?

The alignment of your union must be the largest alignment of any of its members. This is 4. Therefore, the size of the union must be aligned to that size. It could have been 5 (as c is the largest member of the union), but because the alignment of the union as a whole is 4, the size of the union is padded to 8.

What is the size of and union?

When we declare a union, memory allocated for the union is equal to memory needed for the largest member of it, and all members share this same memory space. Since u is a union, memory allocated to u will be max of float y(4 bytes) and long z(8 bytes). So, total size will be 18 bytes (10 + 8).


1 Answers

When you placed the union inside the struct, you didn't mark the union as packed. The unpacked union has a little padding (four bytes) so that its size is a multiple of the size of uint64_t.

The packed union doesn't have this padding, so it is smaller.

As a side observation, the anonymous struct inside the union is not marked packed. That happens not to matter in this case, because everything is nicely aligned anyway - but it's something to be aware of.

like image 173
Martin Bonner supports Monica Avatar answered Oct 22 '22 01:10

Martin Bonner supports Monica