Linux uses a macro called container_of in kernel
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#define container_of(ptr, type, member) ({ \
const typeof(((type *)0)->member) * __mptr = (ptr); \
(type *)((char *)__mptr - offsetof(type, member)); })
BSD has one
#define CONTAINING_RECORD(addr, type, field) \
((type *)((vm_offset_t)(addr) - (vm_offset_t)(&((type *)0)->field)))
and so does windows
#define CONTAINING_RECORD(address, type, field) ((type *)( \
(PCHAR)(address) - \
(ULONG_PTR)(&((type *)0)->field)))
( These were all found at http://stackoverflow.com/questions/8240273/a-portable-way-to-calculate-pointer-to-the-whole-structure-using-pointer-to-a-fi )
I've written the linux version as a C++ template.
template<class P, class M>
size_t offsetof(const M P::*member)
{
return (size_t) &( reinterpret_cast<P*>(0)->*member);
}
template<class P, class M>
P* container_of(M* ptr, const M P::*member)
{
return (P*)( (char*)ptr - offsetof(member));
}
This has the added benefit of being able to 'step-into' the function, unlike a macro call. But this also requires it to be done in C++, and not C.
In C you would call the macro container_of( pointer, Foo, bar)
In C++ you would call the function container_of( pointer, &Foo::bar )