, . , , undefined. - , , . . , :
void allocate(void *sp, size_t n, ... ) {
void **sv = sp;
size_t arg, total = 0;
size_t args = 0;
va_list ap;
va_start(ap, n);
while ((arg = va_arg(ap, size_t)) != 0) {
total += arg;
++args;
}
va_end(ap);
*sv = calloc(...);
sv[1] = sv[0];
va_start(ap, n);
while (--args > 0) {
++sv;
sv[1] = (char *)sv[0] + va_arg(ap, size_t);
}
va_end(ap);
}
allocate(a, n, sizeof(type_x), sizeof(type_y), (size_t)0);
allocate(b, n, sizeof(type_w), sizeof(type_y), sizeof(type_z), (size_t)0);
.
. , . :
void allocate_##Type (struct Type *sp, size_t n) { \
_Pragma("pop_macro(\"X\")") \
size_t total = 0 \
X_Fields \
; \
void *p; \
sp->buffer = calloc(sizeof(*sp) + total); \
p = sp->buffer; \
_Pragma("pop_macro(\"X\")") \
X_Fields \
; \
}
CREATE_ALLOCATOR(A, X(x) X(y))
CREATE_ALLOCATOR(B, X(w) X(y) X(z))
X, CREATE_ALLOCATOR:
#ifdef X
#undef X
#endif
#define X(A) ; sp->A = p; p = sp->A + n
#pragma push_macro("X")
#undef X
#define X(A) + sizeof(sp->A)
#pragma push_macro("X")
#undef X