2

in some codebase I see a definition of the container_of() macro like this:

#ifndef container_of
#ifdef __GNUC__
#define container_of(ptr, type, member) \
    ({ \
        const typeof(((type *)0)->member) *__mptr = (ptr); \
        (type *)( (char *)__mptr - offsetof(type, member) ); \
    })     /* definition 1 */
#else
#define container_of(ptr, type, member) \
    ((type *)((char *)(ptr) - offsetof(type, member)))  /* definition 2 */
#endif
#endif // container_of

To me, definition 2 seems reasonable enough, whereas in definition 1 the author use GCC's typeof keyword to obtain the type of ptr, and then cast it to char *, rendering the typeof statement useless.

What is the rationale behind definition 1? And if definition 1 is actually useful, what are two definitions's pros and cons?

walkerlala
  • 1,599
  • 1
  • 19
  • 32

0 Answers0