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
bufmember 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. Sincebufis 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
bufwas a char * we would have to perform two dynamic allocations, first for a struct sdshdr * and then again forbufand 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 onefreeis 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.1has a nice example that shows how to use this feature: