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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…