Упакованы ли структуры, содержащие упакованные структуры?

Предположим, у меня есть структура, которая содержит другие структуры, которые не упакованы:

struct ContainerOfNonPacked
{
NonPacked1 first;
NonPacked2 second;
};

И тогда у меня есть структура, которая содержит другие структуры, которые упакованы:

struct ContainerOfPacked
{
Packed1 first; // declaration of struct had __attribute__((packed))
Packed2 second; // ditto
};

Первый не будет упакован компилятором (то есть нет гарантии, что внутри структуры не будет «дыр»). Возможно, в нем нет дыр, но вопрос не в этом.

Как насчет второго контейнера, который содержит упакованные структуры? Есть ли гарантия что структура, состоящая исключительно из упакованных структур как ее полей, сама упакована?

2

Решение

Редактировать: это зависит от компилятора и не зависит от поведения.

Для случая GCC и clang структуры, которые содержат только упакованные структуры, сами «упакованы». У них не будет никаких дополнительных «дырок» в них.

Вот пример, чтобы проиллюстрировать (ссылка Godbolt: https://godbolt.org/g/2noSpP):

У нас есть четыре структуры: Packed1, Packed2, NonPacked1 и NonPacked2.

#include <cstdint>

struct Packed1
{
uint32_t a;
uint64_t b;
} __attribute__((packed));

struct NonPacked1
{
uint16_t a;
// Padding of 2 bytes
uint32_t b;
uint8_t c;
};

// We have two structs of the same size, one packed and one not
static_assert(sizeof(NonPacked1) == 12);
static_assert(sizeof(Packed1) == 12);

struct Packed2
{
uint64_t a;
uint64_t b;
} __attribute__((packed)); // packing has no effect, but better for illustration

struct NonPacked2
{
uint32_t a;
// Padding of 4 bytes
uint64_t b;
};

// And again, two structs of the same size
static_assert(sizeof(Packed2) == 16);
static_assert(sizeof(NonPacked2) == 16);

Packed1 и Packed2 входят в структуру ContainerOfPacked, а два других — в ContainerOfNonPacked.

struct ContainerOfNonPacked
{
NonPacked1 first; // 12 bytes
// Padding of 4 bytes between the non-packed struct-fields
NonPacked2 second; // 16 bytes
};

struct ContainerOfPacked
{
Packed1 first; // 12
// No padding between the packed struct-fields
Packed2 second; // 16
};

static_assert(sizeof(ContainerOfNonPacked) == 32);
static_assert(sizeof(ContainerOfPacked) == 28);

Как показывают комментарии кода и статические утверждения, в контейнере упакованных структур нет отверстий для заполнения. Он ведет себя так, как будто он сам «упакован».

Хотя это и есть ответ, я также ищу ответы, которые могут привести соответствующие части Стандарта или некоторые другие авторитетные / теоретические объяснения.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]