Kernel's "container_of" - any way to make it ISO conforming?

c, c99, linked-list, linux-kernel, standards-compliance

Solution

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.

Problem

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)?

Original source