Чуть более читаемая версия:
#define container_of(ptr, type, member) ( \
{ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) ); \
} \
)
Короче говоря, макрос определяет полезный «тест», который можно вставить в оператор if и другие. ((Type *) 0) преобразует NULL-ссылку в рассматриваемый тип, а затем принимает подкомпонент 'member' типа. Макрос typeof () вернет тип, связанный с подэлементом «object». Таким образом, создается постоянная переменная __mptr того же типа, что и подкомпонент type.member. Например, если бы мы имели:
typedef struct foo_s {
int bogus;
int bar;
} foo;
Тогда, если вызвать так:
foo blah; /* and initialize it of course */
int *myptr = &foo.bar;
foo *result = container_of(myptr, foo, bar);
Тогда первая строка макроса превратится в следующее:
const int *__mptr = (myptr);
Затем вторая строка макроса вычисляет позицию в памяти исходной структуры, возвращает указатель памяти структуры и правильно переводит его в эту структуру, а расширенное значение будет выглядеть так:
(foo *)( (char *)__mptr - offsetof(foo, bar));
Результат таков:
foo *result = container_of(myptr, foo, bar);
позволяет вам взять элемент myptr внутри структуры и извлечь из него указатель на исходный контейнер.
Теперь, в приведенном выше примере это бесполезно, потому что у вас уже есть доступ к вмещающей структуре. Но сделайте вид, что вы этого не сделали, потому что API, в котором вы находитесь, не прошел его. Этот макрос - хитрый способ получить родительский контейнер, если у вас его обычно не было бы.
Лучше всего, конечно, создать лучший API, где этот хак не нужен. Но это полезно, если вы c