3

Hi why container_of macro looks like this:

#define container_of(ptr, type, member) ({ \
                const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                (type *)( (char *)__mptr - offsetof(type,member) );})

Is there any risk to use it just as posted below:

#define new_container_of(ptr, type, member) ({ \
                (type *)( (char *)ptr - offsetof(type,member) );})

Since we are casting at the end ptr to char*, why we are doing first macro line at all?

stanleysts
  • 41
  • 3

1 Answers1

4

According to the popular explanation, the

const typeof( ((type *)0)->member ) *__mptr = (ptr);

line is there for extra safety: the additional initialization ensures that the type of ptr is compatible with the type of member.

Without that check one could implement it as

#define new_container_of(ptr, type, member) \
   (type *)( (char *)(ptr) - offsetof(type, member) )

i.e. without using non-standard extensions like those ({ ... }) statement expressions.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765