Separate libraries, without "macro hell".
>>How do you handle types which need to free memory without destructors? Manually loop over the vector and free stuff every time one goes out of scope? That doesn't seem safer to me.
Providing both heap and stack based allocation. E.g. allocating a vector in the stack would require no explicit de-allocation (example: https://github.com/faragon/libsrt). For heap allocation, you would need to call some sometype_free(&a) function, obviously (there is no RAII in C).