3 ms·
I'm trying to understand how this linked list works -- struct list_head { struct list_head *next, *prev; }; struct foo { int fooness
by rrauenza 5y ago
I'm trying to understand how this linked list works --
struct list_head {
struct list_head *next, *prev;
};
struct foo {
int fooness;
struct list_head list;
};
struct foo *iterator;
list_for_each_entry(iterator, &foo_list, list) {
do_something_with(iterator);
}
If we are walking iterator->list->next ... how do we get the pointer of the next enclosing foo struct? Are they doing pointer arithmetic to get the beginning of the struct from the list field offset and casting it to foo?
Ah -- That does seem like what they do:
#define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member); \
&pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
- kragen 5y agoYeah, standard hack for intrusive linked lists in C and similar languages.
- dddnzzz334 5y agoHow do I learn all these pointer hacks in C?
- db48x 5y agohttps://en.cppreference.com/w/cpp/types/offsetof https://en.cppreference.com/w/cpp/types/offsetof