1

我正在使用 godbolt查看以下结构的布局信息:

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

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

我希望这两个结构的布局Foo1Foo2相同的。据我了解,匿名嵌套结构的任何字段都只是“折叠”到父结构中。所以 的布局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是 的两倍大小Foo1data突然似乎有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字段之前会引发错误。

为什么布局Foo1Foo2不同?

4

1 回答 1

2

您的匿名结构是一种独特的类型。因此,它的大小不能为零,因此大小为 1 个字节。 data仍然有一个零大小,但包含它的结构没有。

于 2019-01-24T19:19:53.443 回答