Reading the source code of Redis:
struct sdshdr {
int len;
int free;
char buf[];
};
I found that char buf[]
could not be replace with char *buf
, in the sense that char* buf
would increase the size of struct.
But I don't see why, would anyone shed some light on this?
Edit: I've tested it on my x86_64 Ubuntu(3.2.0-23-generic) with gcc 4.6.3 like this:
printf("sdshdr len = %zu\n", sizeof(struct sdshdr));
With char buf[]
it outputs sdshdr len = 8
and sdshdr len = 16
with char *buf
.
The way the
buf
member is declared is taking advantage of a C99 feature called flexible arrays, the main advantage is to gain the use of variable length array like features inside a struct. Sincebuf
is declared without a size it occupies no space until you explicitly allocate it when dynamically allocating a struct sdshdr *.It is more efficient than using a char * since if
buf
was a char * we would have to perform two dynamic allocations, first for a struct sdshdr * and then again forbuf
and the pointer itself would require additional space. This is cleaner since the allocation either succeeds or fails as a unit and cleaning up is simpler since only onefree
is required. We also gain locality of data since the whole structure is allocated in a block and does not require a separate dereference to accessbuf
.The draft C99 standard in section
6.7.2.1
has a nice example that shows how to use this feature: