The container_of() macro in the Linux kernel is defined as:
#define container_of(ptr, type, member) ({ \\
const typeof( ((type*)0)->member) * __mp
Why this is ((type*)0)->member, not (type*)->member
Simply because (type*)->member would be invalid syntax, thus typeof would be impossible. So it uses a NULL pointer, which it doesn't dereference anyway - it's used just so typeof can refer to the member.
How this works:
The typeof trick is used to declare a pointer of the type of the member. This pointer gets is initialized with the pointer passed by the caller
The offset of that member in the struct is subtracted from the address of the pointer: this yields the address of the containing object
Subtler issue: why not get rid of typeof and just do ptr - offsetof. We're casting it to char * anyway, right ? In that case you could pass anything as ptr and the compiler won't say a thing. So the whole typeof things is there for (rudimentary) type checking.