2011-05-21 9 views
30

En la implementación de las listas de kernel de Linux en /include/linux/list.h, ¿cuál es el razonamiento detrás de la primera línea (pegado debajo) de la macro container_of?Justificación detrás del contenedor_de macro en linux/list.h

const typeof(((type *)0)->member) *__mptr = (ptr); 

En un código de ejemplo de la mina, que eliminan esta línea y cambió la definición de

#define container_of(ptr, type, member) ({      \ 
    (type *)((char *)ptr - offsetof(type,member));}) 

y mi código todavía mostraron resultados esperados. ¿La primera línea es redundante? ¿O tiene alguna trampa oculta de la que no tengo conocimiento?

El código que he encontrado en Faq/LinkedLists

/** 
* container_of - cast a member of a structure out to the containing structure 
* @ptr:  the pointer to the member. 
* @type:  the type of the container struct this is embedded in. 
* @member:  the name of the member within the struct. 
* 
*/ 
#define container_of(ptr, type, member) ({      \ 
     const typeof(((type *)0)->member) *__mptr = (ptr); \ 
     (type *)((char *)__mptr - offsetof(type,member));}) 

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 

Respuesta

33

Se añade un poco de comprobación de tipos. Con su versión, esta compila bien (sin previo aviso):

struct foo { int bar; }; 

.... 

float a; 
struct foo *var = container_of(&a, foo, bar); 

con la versión del kernel, los informes del compilador:

warning: initialization from incompatible pointer type 

buena explicación de cómo funciona la macro: container_of de Greg Kroah-Hartman.

Cuestiones relacionadas