2012-09-03 13 views
10

Sulla definizione della struttura seguente, c'è una riga con una definizione di macro (#define). Cosa fa esattamente quella linea? Capisco che fa un alias alla prima voce dell'array h_addr_list, ma a me sembra ancora strano. h_addr un membro della struct hostent? Questa definizione è solo nell'ambito della struttura?definizione della macro all'interno della definizione di struct

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 */ 
}; 

risposta

16

La definizione della macro non è del tutto circoscritta, funzionerebbe allo stesso modo se fosse stata definita all'esterno di quella struttura.

Permette vecchio codice di continuare ad utilizzare hr.h_addr piuttosto che dover essere cambiato a he.h_addr_list[0] (supponendo he è una struct hostent).

Per chiarire, h_addr non è un campo di struct hostent. Tale definizione viene elaborata dal preprocessore , il compilatore effettivo vede una riga vuota in cui è lo #define.
Ma se un pezzo di codice è scritto come he.h_addr, il pre-processore lo modificherà e lo sostituirà con he.h_addr_list[0]. Questo è ciò che il vero compilatore vedrà.

Le macro del pre-processore non hanno mai un ambito: il compilatore proprio non le vede nemmeno - vede solo il risultato delle sostituzioni e il pre-processore ignora completamente (non ne è a conoscenza).

+0

Capisco la tua risposta solo parzialmente. Ad esempio, perché 'h_addr' è un membro di' struct hostent' quando è solo una macro? – pap42

+2

'h_addr' non è un campo di' struct hostent'. Tale definizione viene elaborata dal pre-processore, il compilatore effettivo vede una riga vuota dove è il '# define'. Ma se un pezzo di codice è scritto come 'he.h_addr', il pre-processore lo modificherà e lo sostituirà con' he.h_addr_list [0] '. Questo è ciò che il vero compilatore vedrà. – Mat

+0

La tua risposta è eccellente, ma penso che dovresti modificarlo per renderlo un po 'più chiaro per i futuri lettori (forse includendo il commento che hai appena fatto?). – pap42

5

Una volta definito, un identificatore di macro rimane visibile indipendentemente dalle regole di ambito C. Il suo ambito inizia alla sua definizione, fino alla fine dell'unità di traduzione o una corrispondente direttiva #undef.

Qui, la definizione all'interno della struttura è solo per la leggibilità; puoi anche definire la tua macro dopo la tua struttura ad esempio:

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] 

Non è un campo; consente all'utente di scrivere s.h_addr anziché s.h_addr_list[0].

0

Le definizioni di macro non hanno ambito, quindi questa macro è visibile all'interno delle unità di compilazione che visualizzano questa definizione e fino a undef h_addr.

Problemi correlati