Esta macro se utiliza para encontrar la dirección de una estructura dada uno de sus miembros.
Así, por ejemplo, suponga que tiene la estructura:
typedef struct
{
int i;
int j;
} typestruct;
Lo primero que debe saber es que la última parte de la macro:
&((typestruct *)0)->j
se utiliza para dar el offset de un miembro. Por lo tanto, es el tamaño, en bytes, de zero memoria que se aplica al tipo, al miembro. En este caso, es el sizeof(int)
, porque j
es justo debajo de int i
; Asumamos que esta expresión vale 4
por simplicidad. Se puede obtener el mismo resultado con la macro
offsetof(typestruct, j);
Ahora queremos calcular la dirección de temp
, donde temp
es typestruct temp
. Para hacer eso, calculamos simplemente la dirección del puntero menos la posición del miembro.La dirección del puntero es:
(typestruct *)((char *) &temp.j)
Por lo tanto, la resta es:
&temp == (typestruct *)((char *) &temp.j) - offsetof(typestruct, j)
o, como en la macro dice:
&temp == (typestruct *)((char *) &temp.j) - &((typestruct *)0)->j
Usted puede aprender mucho más here, y también en este question.
(paréntesis son necesarios, pero fue eliminada de aclaración)
Hoy en día [list_entry] (http://lxr.free-electrons.com/ident?i=list_entry) macro [se define] (http : //lxr.free-electrons.com/source/include/linux/list.h) como [container_of] (http://lxr.free-electrons.com/ident?i=container_of) macro (que es casi idéntica) a la antigua versión de 'list_entry' que publicaste) que fue explicada en gran medida por [Radek Pazdera] (https://github.com/pazdera) en [su blog] (http://radek.io/2012/11/10/ mágico-contenedor_de-macro /). Hasta donde sé, este cambio se realizó entre la versión del núcleo [2.4.37] (http://lxr.free-electrons.com/source/include/linux/list.h?v=2.4.37) y '2.6. 11'. –