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?