Для будущих поисков (ы): это лучшее объяснение, которое я нашел до сих пор:
http://psomas.wordpress.com/2009/07/01/weird-kernel-macros-container_of/
В основном (цитата):
"Теперь мы можем понять (хотя бы частично), что делает макрос. Он объявляет указатель на член структуры, на который указывает ptr
, и назначает ему ptr. Теперь __mptr
указывает на тот же адрес, что и ptr
Затем он получает смещение этого member
в пределах struct
и вычитает его из фактического адреса члена struct ‘instance’(ie __mptr)
. Приведение (char *)__mptr
необходимо, так что «арифметика указателей» будет работать какнамеревался, то есть вычесть из __mptr
ровно (size_t)
байтов, которые offsetof
«возвращает». "
, а также два других важных указания (цитата):
"Я действительно не могу понять, почему мы не можем использовать указатель ptr напрямую. Мы можем пропустить первую строку, и макрос может быть
#define container_of(ptr, type, member) (type *)( (char *)(ptr) - offsetof(type,member) )
ptr
используется только один раз - мы неНе нужно беспокоиться о побочных эффектах. Может быть, это просто хорошая практика кодирования. "
и тон позже отредактировал оригинальное сообщение (цитируется):
«По-видимому, первая строка предназначена для« проверки типов ».Это гарантирует, что type
имеет член с именем member
(однако, я думаю, это также делается с помощью макроса offsetof
), и если ptr
не является указателем на правильный тип (тип * 1034)*), компилятор выведет предупреждение, которое может быть полезно для отладки. "