我正在查看以下结构using 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'
但是这些似乎都不能解释布局的差异,也不能暗示未定义的行为。而且,文档:Anonymous structs也没有。
作为记录,我确实知道此代码依赖于MSVC扩展:
warning C4200: nonstandard extension used: zero-sized array in struct/union
warning C4201: nonstandard extension used: nameless struct/union
“零大小数组” data
似乎是灵活的数组成员,因为将其放在size
字段之前会引发错误。
Foo1
和Foo2
的布局为何不同?
答案 0 :(得分:2)
您的匿名结构是一种独特的类型。因此,它的大小不能为零,因此大小为1个字节。 data
的大小仍然为零,但包含该大小的结构却没有。