Search code examples
cstructsizeofstructure-packing

Unexpected size when a struct has a union


I am trying to verify the size of a struct. For some reasons, it's giving me a size of 18 rather than the expected 14 bytes (the union should have a max of 8 + 2 + 2 = 12 bytes). Can someone help me?

typedef struct __attribute__((__packed__)) def
{
        union {
                double x;   /* 8 bytes */
                char *y;    /* 8 bytes as for 64-bit system */
                struct {
                        struct def *array; /* 8 bytes */
                        unsigned short a;  /* 2 bytes */
                        unsigned short b;  /* 2 bytes */
                } z;
        } w;
        unsigned short v;  /* 2 bytes */
} DEF, *DEFP;

int main(int argc, char **argv) {
        printf("size of DEF = %lu\n", sizeof(DEF));
        printf("size of unsigned short = %lu\n", sizeof(unsigned short));
        printf("size of struct def * = %lu\n", sizeof(struct def *));
        printf("size of char * = %lu\n", sizeof(char *));
        printf("size of double = %lu\n", sizeof(double));
}

Here's what it displays when I run it:

$ gcc test.c && ./a.out
size of DEF = 18
size of unsigned short = 2
size of struct def * = 8
size of char * = 8
size of double = 8

Solution

  • __attribute__((__packed__)) refers to struct def only. It does not pack the anonymous struct inside the anonymous union inside struct def.

    So most likely those two members

                       unsigned short a;  /* 2 bytes */
                       unsigned short b;  /* 2 bytes */
    

    "use" 4 but 2 bytes.


    Unrelated to your question: C mandates to print size_ts using the z length modifier:

     printf("size of DEF = %zu\n", sizeof (DEF));