1

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異なるのはなぜですか?

4

1 に答える 1