Итак, есть понятие «эффективный тип» для объектов без собственного объявленного типа. (поскольку это вытряхивает, те в значительной степени состоят только из "другого конца указателя * alloc" и пары странных правил объединения)
По сути, «эффективным типом» такого объекта является то, что вы в последний раз использовали для его назначения, не считая раз, которые были char
или char[]
по причинам.
Одно интересное взаимодействие связано с правилами объявления типов структур. А именно, вы можете свободно повторно объявлять одно и то же имя тега (или отсутствие имени тега), и каждое объявление вводит совершенно новый тип (прошлые имена затемняются, но объекты со старыми типами не интерпретируются повторно).
Так что вы можете сделать что-то вроде этого:
# define DECL_VECTOR(NAME,TYPE,SIZE) PUN_STRUCT(NAME,TYPE,SIZE) INIT_STRUCT(NAME,TYPE,SIZE)
# define PUN_SIZE sizeof(void*)+sizeof(int)*2
# define PUN_STRUCT(NAME,TYPE,SIZE) \
struct { \
TYPE (*p)[(SIZE)]; \
int size; \
int capacity; \
} *NAME = malloc(PUN_SIZE);
# define INIT_STRUCT(NAME,TYPE,SIZE) do { \
if (!NAME) { \
perror("malloc fail"); \
abort(); \
}else { \
NAME->size = (SIZE); \
NAME->capacity = 0; \
NAME->p = malloc(sizeof(*NAME->p)); \
if (!NAME->p) { \
perror("malloc fail"); \
abort(); \
} \
NAME->p = (TYPE(*)[(SIZE)])(NAME->p); \
} \
}while(false)
int main(int argc, char *argv[])
{
DECL_VECTOR(vec1,int,8);
printf("size of handle struct: %zu,\n\
size of vector array: %zu,\n\
size of vector element: %zu\n\
address of handle struct: %p,\n\
address of vector array: %p\n", sizeof(*vec1), \
sizeof(*vec1->p), \
sizeof(*vec1->p[0]), \
vec1, \
vec1->p);
free(vec1->p);
free(vec1);
return 0;
}
(однако, люди могут обвинить вас в злоупотреблении вашими привилегиями макросов, и они могут не ошибаться)