Структура структуры MSVC изменяется при переносе гибкого массива в анонимную структуру? - PullRequest
0 голосов
/ 24 января 2019

Я просматриваю информацию о расположении для следующих структур , используя 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 Ответ

0 голосов
/ 24 января 2019

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

...