Linux
Linux is an open-source, Unix-like, POSIX-compliant kernel. The name Linux is also commonly used to describe operating systems that are based on the kernel.
container_of
and __same_type
macro
The macro container_of
is used extensively (>20.000 times) in the Linux kernel
to get a pointer to the struct containing the given member.
#define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)((char *)__mptr - offsetof(type,member));})
It uses the GNU C extension of statement expressions.
It is used to enable the functionality of various datastructures (e.g. lists and
queues) without wrapping the type into them (as would be done in C++ using
templates, e.g. std::list<MyType>
)
Since Linux has moved to use C11, the macro also includes a static_assert
type
check.
/* Are two types/vars the same type (ignoring qualifiers)? */ #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) /* new C11 version */ #define container_of(ptr, type, member) ({ \ void *__mptr = (void *)(ptr); \ _Static_assert(__same_type(*(ptr), ((type *)0)->member) || \ __same_type(*(ptr), void), \ "pointer type mismatch in container_of()"); \ ((type *)(__mptr - offsetof(type, member))); }) int main() { const char a; char b; if (__same_type(a,b)) { printf("yes\n"); } else { printf("no\n"); } }