¿Cómo devuelve la función &((myStruct *)0)->x el desplazamiento del miembro x en el tipo myStruct?
typedef struct {
unsigned char y;
unsigned short int x;
} myStruct;
void main(void) {
unsigned char offset = &((myStruct *)0)->x;
printf("Offset=%d\n", offset);
}
usando esta mágica expresión de macro &((myStruct*)0)->x
se obtiene el desplazamiento del miembro x
en myStruct
! ¿Alguien puede ayudarme a entender cómo se asigna memoria? Investigando en Google descubrí que se crea un puntero de tipo myStruct
que tiene la dirección 0
y luego se calcula la dirección del miembro x
, lo que dará el valor del desplazamiento. No entiendo cómo el puntero apunta a la dirección 0
. ¿Cómo lo hace el compilador? ¿Y la dirección 0
es una dirección virtual cargada en tiempo de ejecución (en la función principal de la pila) para hacer esto? ¡Gracias de antemano!
davy.ai
La expresión
&((myStruct*)0)->x
es una manera de calcular el desplazamiento del miembrox
enmyStruct
. Funciona definiendo un puntero de tipomyStruct
que apunta a la dirección de memoria0
. Dado que esta es una dirección de memoria inválida, esto no asigna en realidad ninguna memoria. El operador->
se utiliza luego para acceder al miembrox
de la estructuramyStruct
a la que apunta el puntero. Tomando la dirección de este miembro con el operador&
, se obtiene el desplazamiento dex
enmyStruct
.En resumen, la expresión
&((myStruct*)0)->x
funciona porque define un puntero a unmyStruct
inexistente en la dirección de memoria0
, lo que permite calcular el desplazamiento del miembrox
. Este es un truco ingenioso que aprovecha el hecho de que el valor0
es un caso especial en C que puede interpretarse como un puntero nulo.