Why this 0 in ((type*)0)->member in C?

前端 未结 2 651
独厮守ぢ
独厮守ぢ 2020-12-14 17:31

The container_of() macro in the Linux kernel is defined as:

#define container_of(ptr, type, member) ({ \\
        const typeof( ((type*)0)->member) * __mp         


        
相关标签:
2条回答
  • 2020-12-14 18:14

    Because type* is a type and not a valid instance of the structure.

    The pointer to zero is used to get a proper instance, but as typeof is resolved at compile-time and not at run-time the address used in the pointer doesn't have to be a proper or valid address.

    0 讨论(0)
  • 2020-12-14 18:22

    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.

    0 讨论(0)
提交回复
热议问题