Context
I have some functions to support using a custom memory allocator in my library:
void *(allocate)(struct allocator *allocator, size_t size, size_t alignment);
void (deallocate)(struct allocator *allocator, void *pointer, size_t size, size_t alignment);
There’s two things that I would still like to improve upon with this interface:
- There is a need to write
sizeof(type)
andalignof(type)
for every allocation and deallocation. - The type
void *
allows mistakenly using a pointer to a type with invalid size or alignment.
Both of these can be fixed with some simple macros:
#define allocate(allocator, type, count)
(type *)(allocate)(allocator, sizeof(type) * (count), alignof(type))
#define deallocate(allocator, pointer, type, count)
do {
type *typed_pointer = pointer;
(deallocate)(allocator, typed_pointer, sizeof(type) * (count), alignof(type));
} while (0)
The macro takes care of calling sizeof(type)
and alignof(type)
, and also performs a cast of the pointer to the given type so the compiler issues a warning when it is used as a different type.
Problem
deallocate
does not have a return value, so we can implement it as a block with a variable to perform the implicit pointer cast. But for a function that does return a value, maybe reallocate
, we cannot type check the pointer that is passed to the macro in the same way.
Is there any way to perform this “type checking” implicit cast inline inside of an expression, such that the macro can have a result?