1

Eu vou acrescentar um comentário, mais como curiosidade.

No exemplo acima:
struct fox {
unsigned long weight;
bool is_fantastic;
struct list_head list;
};

O primeiro item do "struct fox" é "weight" e o último é "list".
Se "list" for colocado como primeiro item da struct, o endereço de memória de "list" passa a ser o mesmo endereço de memória da struct "fox":
struct fox {
struct list_head list;
unsigned long weight;
bool is_fantastic;
};

Ou seja (&fox == &fox.list).

Isso acontece porque a alocação de memória dos itens dentro do buffer da "struct fox" é feita na mesma órdem em que esses ítens foram declarados, e o item que estiver na posição zero do buffer, tem o mesmo endereço físico que o início do buffer.
Se fosse feito dessa forma, a macro "container_of" se tornaria desnecessária.

Um símples cast de ponteiro ja seria o bastante:
endereço da struct fox = (struct fox *) endereço do campo list;

Eu aprendi isso num projeto de uma empresa de telecomunicações que eu trabalhei.

Carregando publicação patrocinada...