简体   繁体   中英

Getting the size of the type of a zero-length array element in a structure

Maybe the title is confusing, but the idea is simple. Given the following structure:

struct z {
    uint64_t _a;
    uint64_t _b;
    struct {
        char _c[64];
        uint64_t _d;
    } data[0];
} __attribute__((packed));

How might one get the size of the type of the anonymous inner struct data ? I do not want to name the struct and clutter the namespace, but I do need its size when computing the total length of what a serialized buffer would look like with a non-zero data trailer.

If you try this you'll find something similar to:

struct z *p;
sizeof(struct z) == 16
sizeof(*p) == 16
sizeof(p->data) == 0

These results are expected. However, what I was hoping to see was the following:

sizeof(typeof(p->data)) == 72

But, unfortunately, I still get

sizeof(typeof(p->data)) == 0

I thought it might be because the struct was unnamed, but after providing it with a name you'll find the earlier results are still true.

Is there a way to get the size of an anonymous inner zero-length structure?

I would use:

sizeof(p->data[0])

Because it's inside sizeof and therefore not evaluated, p->data[0] does not actually dereference p->data . The compiler only figures out the type.

but I do need its size when computing the total length of what a serialized buffer would look like with a non-zero data trailer

You can't do that with sizeof() . You must keep track of the size yourself.

Per the GCC documentation (bolding mine - and note it well):

Declaring zero-length arrays is allowed in GNU C as an extension. A zero-length array can be useful as the last element of a structure that is really a header for a variable-length object:

 struct line { int length; char contents[0]; }; struct line *thisline = (struct line *) malloc (sizeof (struct line) + this_length); thisline->length = this_length;

Although the size of a zero-length array is zero , an array member of this kind may increase the size of the enclosing type as a result of tail padding. ...

Note how the example code keeps track of the number of elements in the array.

just name it. if instead of saying

struct {
    char _c[64];
    uint64_t _d;
} data[0];

you say

struct data {
    char _c[64];
    uint64_t _d;
} data[0];

then sizeof(struct data) will tell you it's sizeof.

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