3 ms·
printf("%zu %d\n", list_len(l), *l[0]); // Prints 1 1. This prints raptors unless your list is of size_t. #define list_lenref(l) ((size_t*)l)[-1] The only
by 0x09 11y ago
printf("%zu %d\n", list_len(l), *l[0]); // Prints 1 1.
This prints raptors unless your list is of size_t.
#define list_lenref(l) ((size_t*)l)[-1]
The only way to write this kind of size-prefixed plain array in legal C will involve separate getter/setters to explicitly copy the size in and out. It's not as simple as getting a reference because you cannot recast an arbitrary array as a pointer to size_t and read/write to it. A compiler might be happy to optimize these accesses out altogether.
size_t list_len(void* l) {
size_t tmp;
memcpy(&tmp, ((char*)l) - sizeof(size_t), sizeof(size_t));
return tmp;
}
void list_set_len(size_t length) {
memcpy(((char*)l) - sizeof(size_t), &s, sizeof(size_t));
}
Or if you prefer crazy macros
#define list_len(l) (*(size_t*)memcpy(&(size_t){0},((char*)l)-sizeof(size_t),sizeof(size_t)))
#define list_set_len(l,s) memcpy(((char*)l)-sizeof(size_t),&(size_t){s},sizeof(size_t))
Note the ((char* )l). Pointer arithmetic on void* as used elsewhere in the code is a GNU extension. This is easily fixed by instead casting to char* or u/intptr_t.
Otherwise this style of list is just fine, in fact it's not necessarily limited to pointer types.
- opk 11y agoWhat are "raptors"?