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?