Структура структуры MSVC изменяется при переносе гибкого массива в анонимную структуру?

Я смотрю информацию о макете для следующих структур, используя godbolt:

struct Foo1 {
    int size;
    void *data[];
};

struct Foo2 {
    int size;
    struct {
        void *data[];
    };
};

Я ожидал макет для обеих структур Foo1 а также Foo2 быть таким же. Из того, что я понимаю, любые поля анонимной вложенной структуры просто "складываются" в родительскую структуру. Итак, макет Foo2 должно получиться так же, как Foo1,

Однако макеты сгенерированы MSVC 19.16 и отображаются при использовании флага /d1reportSingleClassLayoutFoo различаются:

class Foo1  size(8):
    +---
 0  | size
    | <alignment member> (size=4)
 8  | data
    +---
class Foo2  size(16):
    +---
 0  | size
    | <alignment member> (size=4)
    | <anonymous-tag> <alignment member> (size=8)
 8  | data
    | <alignment member> (size=7)
    +---

Foo2 в два раза больше Foo1, А также data вдруг кажется, имеет размер 1 байт.

Есть некоторые предупреждения, генерируемые с -Wall:

warning C4200: nonstandard extension used: zero-sized array in struct/union
note: This member will be ignored by a defaulted constructor or copy/move assignment operator
warning C4820: 'Foo1': '4' bytes padding added after data member 'Foo1::size'
warning C4200: nonstandard extension used: zero-sized array in struct/union
note: This member will be ignored by a defaulted constructor or copy/move assignment operator
warning C4820: 'Foo2::<anonymous-tag>': '7' bytes padding added after data member 'Foo2::data'
warning C4201: nonstandard extension used: nameless struct/union
warning C4820: 'Foo2': '4' bytes padding added after data member 'Foo2::size'

Но ни один из них, кажется, не объясняет разницу в макете или подсказку к неопределенному поведению. И также не док: Аноним строит.

Кстати, я знаю, что этот код опирается на расширения MSVC:

warning C4200: nonstandard extension used: zero-sized array in struct/union
warning C4201: nonstandard extension used: nameless struct/union

"Массив нулевого размера" data кажется гибким членом массива, так как помещая его перед size поле выдает ошибку.

Почему макеты Foo1 а также Foo2 отличаются?

1 ответ

Решение

Ваша анонимная структура - это отдельный тип. Как таковой, он не может иметь нулевой размер и, следовательно, имеет размер 1 байт. data все еще имеет нулевой размер, но структура, которая его содержит, не имеет.

Другие вопросы по тегам