简体   繁体   中英

MSVC struct layout changes when wrapping flexible array in anonymous struct?

I'm looking at layout info for the following structs using godbolt :

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

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

I'd expected the layout for both structs Foo1 and Foo2 to be the same. From what I understand, any fields of an anonymous nested struct are simply "folded" into the parent struct. So the layout of Foo2 should turn out the same as that of Foo1 .

However, the layouts generated by MSVC 19.16, and displayed when using the flag /d1reportSingleClassLayoutFoo differ:

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 is double the size of Foo1 . And data suddenly seems to have a size of 1 byte.

There are some warning generated with -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'

But none of these seem to explain the difference in layout, or hint towards undefined behavior. And, neither does the doc: Anonymous structs .

For the record, I do know that this code is relying on MSVC extensions:

warning C4200: nonstandard extension used: zero-sized array in struct/union
warning C4201: nonstandard extension used: nameless struct/union

The "zero-sized array" data seems to be a flexible array member, since putting it before the size field throws an error.

Why do the layouts of Foo1 and Foo2 differ?

Your anonymous struct is a distinct type. As such, it cannot have a zero size, and therefore has a size of 1 byte. data still has a zero size, but the struct that contains it does not.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM