2012-09-03 30 views
10

En la definición de la estructura siguiente, hay una línea con una definición de macro (#define). ¿Qué hace esa línea exactamente? Entiendo que hace un alias a la primera entrada de la matriz h_addr_list, pero todavía me parece extraño. ¿Es h_addr un miembro de la estructura hostent? ¿Está esta definición solo dentro del alcance de la estructura?definición de macro dentro de la definición de estructura

struct hostent 
{ 
    char *h_name;  /* official name of host */ 
    char **h_aliases; /* alias list */ 
    int  h_addrtype;  /* host address type */ 
    int  h_length;  /* length of address */ 
    char **h_addr_list; /* list of addresses from name server */ 
    #define h_addr h_addr_list[0] /* address, for backward compatiblity */ 
}; 

Respuesta

16

La definición de macro no tiene ningún ámbito, funcionaría de la misma manera si se definiera fuera de esa estructura.

Permite código antiguo para continuar usando hr.h_addr en lugar de tener que ser cambiado a he.h_addr_list[0] (suponiendo he es una struct hostent).

Para aclarar, h_addr no es un campo de struct hostent. Esa definición es procesada por el preprocesador , el compilador real ve una línea vacía donde está el #define.
Pero si un fragmento de código se escribe como he.h_addr, el preprocesador lo modificará y lo reemplazará por he.h_addr_list[0]. Eso es lo que verá el compilador real.

Las macros de preprocesador nunca se analizan: el compilador propiamente dicho ni siquiera las ve: solo ve el resultado de las sustituciones, y el preprocesador ignora (no tiene conocimiento) del alcance por completo.

+0

Entiendo su respuesta solo parcialmente. Por ejemplo, ¿por qué 'h_addr' es un miembro de' struct hostent' cuando solo es una macro? – pap42

+2

'h_addr' no es un campo de' struct hostent'. Esa definición es procesada por el preprocesador, el compilador real ve una línea vacía donde está el '# define'. Pero si un fragmento de código se escribe como 'he.h_addr', el preprocesador lo modificará y lo reemplazará con' he.h_addr_list [0] '. Eso es lo que verá el compilador real. – Mat

+0

Su respuesta es excelente, pero creo que debería editarla para que sea un poco más clara para los lectores en el futuro (tal vez incluyendo el comentario que acaba de hacer). – pap42

5

Una vez definido, un identificador de macro permanece visible independientemente de las reglas de delimitación de C. Su alcance comienza en su definición, hasta el final de la unidad de traducción o una directiva correspondiente #undef.

Aquí, la definición dentro de la estructura es solo para la legibilidad; también puede definir su macro después de su estructura, por ejemplo:

struct hostent 
{ 
    char *h_name; 
    char **h_aliases; 
    int h_addrtype; 
    int h_length; 
    char **h_addr_list; 
}; 

#define h_addr h_addr_list[0] 

No es un campo en absoluto; permite al usuario escribir s.h_addr en lugar de s.h_addr_list[0].

0

Las definiciones de macro no tienen un ámbito, por lo que esta macro es visible dentro de las unidades de compilación que ven esta definición y hasta undef h_addr.

Cuestiones relacionadas