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