2010-10-07 8 views
9

He comenzado a leer el comentario de los Leones en Unix v6. Encontré estos fragmentos, que nunca he visto utilizar en el lenguaje C. El autor proporciona alguna clase de explicación, pero ¿podría alguien explicarme qué está pasando aquí?Estructuras anónimas en C encontradas en Unix Kernel

params.h:

SW 0177570 
...... 
struct { int integ; }; 

y esto utiliza en unix/prf.c

if(SW->integ == 0) 

Explicación por el autor

SW se define previamente como el valor 0177570. Esta es la dirección del núcleo de un registro de procesador de solo lectura que almacena la configuración del registro de conmutador de consola. El significado de la declaración es claro: obtenga el contenido en la ubicación 0177570 y vea si son cero. El problema es expresar esto en C. El código if (SW == 0) no habría transmitido este significado. Claramente SW es un valor de puntero que debe ser desreferenciado. El compilador podría haber sido cambiado para aceptar if (SW-> == 0) pero tal como está, esto es sintácticamente incorrecto. Al inventar una estructura ficticia, con un elemento integ, el programador ha encontrado una solución satisfactoria a su problema.

Mi pregunta principal es cómo funciona esto? Cuando el compilador ve SW->integ, ¿cómo se asocia SW con la estructura anónima?

Respuesta

6

IIRC, los compiladores de C antiguos conservaban todos los nombres de campo (como integ) en un solo espacio de nombres en lugar de crear un espacio de nombres por tipo struct. Tampoco distinguieron entre struct punteros y int punteros, por lo que cada puntero tiene un campo integ correspondiente a su primer sizeof(int) bytes. Dado que integ es el primer valor en struct y tiene el tipo int, SW->integ corresponde a *((int *)SW).

+2

En C moderna usaríamos 'int * const SW = 0177570;' Pero antes del advenimiento de optimizadores, eso le hubiera costado a Ken y su grupo dos bytes costosos :) –