I've read about the Cello fat pointer library and wanted to know if prepending a header to some data is actually allowed in C, e.g. something like this:
struct header
{
size_t length;
};
char* create_string(const char* cstr)
{
void* ret = malloc(sizeof(struct header)+strlen(cstr)+1);
((struct header*)ret)->length = strlen(cstr);
strcpy((char*)ret + sizeof(struct header), cstr);
return (char*)ret + sizeof(struct header);
}
size_t get_length(const char* sized_string)
{
struct header* tmp = sized_string - sizeof(struct header);
return tmp->length;
}
This example is a string, but it could be anything else that is stored, maybe even something that isn't an array, in which case the header could have different kinds of metadata.
I know that sds uses flexible array members, but that requires c99 and isn't quite as flexible as this aproach (unless you just used a generic char array and recast it as needed).
Specifically in this question people say the following is not actually portable:
struct header {
size_t len;
unsigned char data[1];
};
Because accessing data beyond the first element is UB. Another thing is that the lines ((struct header*)ret)->length = strlen(cstr);
and struct header* tmp = sized_string - sizeof(struct header);
look wrong to me (because of the pointer casts) and I don't see a better way to write them.