I was investigating some code I saw that deals with 0-size arrays. Specifically, they are used in the case of dynamically allocated size of a struct such as in https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
Specifically, this is the code in Callgrind:
struct _EventGroup {
int size;
const char* name[0];
};
I was playing around with this, using gcc 4.1.2 on a 64-bit Red Hat, and noticed that the sizeof function returns a size of 8 bytes for the entire struct _EventGroup when the name field is a pointer. Now if I change it to:
struct _EventGroup {
int size;
const char name[0];
};
I get 4 bytes because gcc identifies the 0-size array as taking up no space, and the int as taking up 4 bytes. That makes sense. If I then change it to:
struct _EventGroup {
int size;
const char* name;
};
sizeof returns 16 bytes because the char* takes up 8 bytes in a 64 bit system, and the int has to get padded to 8 bytes. This makes sense. Now, if I do one last change:
struct _EventGroup {
const char* name[0];
};
I get 0 bytes because gcc is detecting my zero-size array. What I want clarified is what's happening in the first case I presented. How much space is gcc allocating for a pointer to a zero size array and why? I'm asking because this code seems designed to be efficient with memory allocation, however it would make sense that gcc either gives the pointer a size of 0 bytes if it detects it points to essentially nothing, or 8 bytes if it is being treated as a normal pointer. Alignment would dictate that I get either 4 bytes or 16 bytes with my original struct. Why am I getting 8 bytes?
Gcc is adding the right amount of padding such that if you actually allocate extra space for the array, the pointer &(eventGroup->name)
will be properly aligned.
It seems you're on a platform that has 4-byte ints and 8-byte pointers, so this means you have:
bytes 0-3 -- the int
bytes 4-7 -- padding
bytes 8-15 -- where the first (char *) would be stored, 8-byte aligned
Since it's actually an array of zero size, you don't actually have that first char *
, but you do have the padding. Hence, the struct has size 8.
In your second example, there is no alignment requirement for a one-byte char, so you have:
bytes 0-3 -- the int
byte 4 -- where the first (char) would be stored, "1-byte aligned"
Again, no actual char
in the struct, so it has size 4.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With