Неожиданный размер, когда структура имеет объединение
Я пытаюсь проверить размер структуры. По некоторым причинам он дает мне размер 18, а не ожидаемые 14 байтов (объединение должно иметь максимум 8 + 2 + 2 = 12 байтов). Кто-нибудь может мне помочь?
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));
}
Вот что отображается при запуске:
$ 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
2 ответа
__attribute__((__packed__))
относится к struct def
только. Он не упаковывает анонимных struct
внутри анонимного union
внутри struct def
,
Так что, скорее всего, эти два члена
unsigned short a; /* 2 bytes */
unsigned short b; /* 2 bytes */
"использовать" 4, но 2 байта.
Не имеет отношения к вашему вопросу: C мандаты на печать size_t
с помощью z
модификатор длины:
printf("size of DEF = %zu\n", sizeof (DEF));
Пишу:
struct foo {
struct bar {
...
} x;
};
Не отличается от написания
struct bar { ... };
struct foo {
struct bar x;
};
Почему это имеет значение? Это важно, потому что во втором примере должно быть очевидно, почему атрибуты, к которым вы применяете foo
не применяется автоматически к bar
, Это означает, что ваша внешняя структура будет упакована, но это не меняет значения компонентов.
Внутренняя структура, которая у вас есть, не будет упакована, и совершенно очевидно, что если она следует обычным правилам выравнивания, большинство архитектур следует ее размеру, то будет кратна наиболее строго выровненному элементу, который будет указателем. Таким образом, размер структуры внутри объединения будет 16, а не 12, как вы предполагали. Это означает, что размер объединения также будет 16.