kErNeL kRaCkEr
04-10-2001, 04:06 PM
I stumbled accross a fairly interesting C macro in the Linux kernel source
that has stumped me. Obviously the macro works, but the syntax/logic is
somewhat hard to swallow. A little enlightenment would be appreciated.
/*
* Macro used to acces an element in a list.
* Type casting a '0' to type* then accessing its member....?
*/
#define list_entry(ptr, type, member) \
((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
/*
* Example of its use
*/
struct super_block {
...
struct list_head s_files;
...
} *sb = &some_super_block;
struct file {
...
struct list_head f_list;
...
} *file;
struct list_head *p;
for (p = sb->s_files.next; p != &sb->s_files; p = p->next) {
struct file *file = list_entry(p, struct file, f_list);
do something to 'file'
}
that has stumped me. Obviously the macro works, but the syntax/logic is
somewhat hard to swallow. A little enlightenment would be appreciated.
/*
* Macro used to acces an element in a list.
* Type casting a '0' to type* then accessing its member....?
*/
#define list_entry(ptr, type, member) \
((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
/*
* Example of its use
*/
struct super_block {
...
struct list_head s_files;
...
} *sb = &some_super_block;
struct file {
...
struct list_head f_list;
...
} *file;
struct list_head *p;
for (p = sb->s_files.next; p != &sb->s_files; p = p->next) {
struct file *file = list_entry(p, struct file, f_list);
do something to 'file'
}