I think it's cleaner to allocate the header information before the actual pointer (or, conversely, to return the pointer sizeof(array_header) into the allocation). Then it's trivial to pass around.
struct vec_header_t {
size_t length;
size_t capacity;
};
static inline struct vec_header_t *vec_to_header(void *vec)
{
return ((struct vec_header_t *)vec) - 1;
}
#define _vec_length(vec) (vec_to_header(vec)->length)
static inline void vec_free(void *vec)
{
if (vec)
free(vec_to_header(vec));
}
#define vec_foreach(vec, iter) \
for ((iter) = (vec); (iter) < ((vec) + vec_length(vec)); ++(iter))
It's slightly more cognitive overhead when, for example, debugging, but the vast improvement in usability (no special macros for normal/static declaration, trivial passing to functions, etc) is worth it IMHO.