While looking at Linux kernel's implementation of doubly linked circular lists, I've found following macro:
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
The way this works is that it returns pointer to structure given only address of one of its members:
struct blabla
{
int value;
struct list_head *list;
}
Thus you can get pointer to blabla (and get to "value") given only pointer to list. To my question, how would I make this as portable as possible (best case conforming to C89/C99?). Due to usage of typeof(), this is gcc only.
This is what I've got so far:
#define container_of(ptr, type, member) ( \
(type *) (char *)(ptr)-offsetof(type,member)\
)
Is this snippet conforming to ISO standards (and thus should be able to be compiled on any conforming compiler)?
As Ouah commented, the ({ ... })
statement expression is a GNU extension; you won't be able to use that. Your core expression is close to what's required, but doesn't have enough parentheses:
#define container_of(ptr, type, member) \
((type *) ((char *)(ptr) - offsetof(type, member)))
That looks clean to me. It's only spread across two lines for SO.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With