Reputation: 19452
How to pass struct type in arguments? I guess it is not possible, still wanted to check if it is feasible.
My requirement is something like this
Below is a macro list_entry
used in linux kernel
#define list_entry(ptr, type, member) \
((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
I want to rewrite it using function. How do I write?
list_entry(void *ptr, ???, ???)
Is there a way we can do this?
I am trying to write a wrapper to free a given list. So to use list_entry in my function, my function needs to be passed with type and the member. Is it possible?
Upvotes: 1
Views: 178
Reputation: 215201
It's fundamentally not possible to write list_entry
, with its same behavior and signature, as a function. This is because its arguments include a type and a member name, neither of which is a value in C.
On the other hand, you could to some extent abstract out the "code" content of the macro into a function:
#define list_entry(ptr, type, member) \
((type *)f_list_entry(ptr, offsetof(type, member)))
static void *f_list_entry(void *ptr, size_t offset)
{
return (char *)(ptr)-offset;
}
But as you can see, the only actual "code" is a single subtraction.
Since I used the standard offsetof
macro rather than the kernel's invocation of undefined behavior via a poor hack, I also took the liberty of fixing the type-correctness (size_t
instead of unsigned long
).
Upvotes: 2