Sandeep
Sandeep

Reputation: 19452

How to pass struct type in arguments?

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

Answers (1)

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

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

Related Questions