Understanding container_of macro in the Linux kernel

c, c-preprocessor, linux-kernel

Solution

Your usage example `container_of(dev, struct wifi_device, dev);` might be a bit misleading as you are mixing two namespaces there.

While the first `dev` in your example refers to the name of pointer the second `dev` refers to the name of a structure member.

Most probably this mix up is provoking all that headache. In fact the `member` parameter in your quote refers to the name given to that member in the container structure.

Taking this container for example:

struct container {
  int some_other_data;
  int this_data;
}

And a pointer `int *my_ptr` to the `this_data` member you'd use the macro to get a pointer to `struct container *my_container` by using:

struct container *my_container;
my_container = container_of(my_ptr, struct container, this_data);

Taking the offset of `this_data` to the beginning of the struct into account is essential to getting the correct pointer location.

Effectively you just have to subtract the offset of the member `this_data` from your pointer `my_ptr` to get the correct location.

That's exactly what the last line of the macro does.

Problem

When I was browsing the Linux kernel, I found a `container_of` macro which is defined as follows: ``` #define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)((char *)__mptr - offsetof(type,member));}) ``` I understand what does container_of do, but what I do not understand is the last sentence, which is ``` (type *)((char *)__mptr - offsetof(type,member));}) ``` If we use the macro as follows: ``` container_of(dev, struct wifi_device, dev); ``` The corresponding part of the last sentence would be: ``` (struct wifi_device *)((char *)__mptr - offsetof(struct wifi_device, dev); ``` which looks like doing nothing. Could anybody please fill the void here?

Original source

Related problems