2012-09-03 200 views
10

在下面的結構定義中,有一行包含宏定義(#define)。這條線究竟做了什麼?我知道它是數組h_addr_list的第一個條目的別名,但它對我來說仍然很奇怪。 h_addr是struct hostent的成員嗎?這個定義是否只在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 */ 
}; 

回答

16

宏定義根本沒有作用域,如果它在該結構之外被定義,它將以相同的方式工作。

它允許舊代碼繼續使用hr.h_addr而不是必須更改爲he.h_addr_list[0](假設hestruct hostent)。

爲了澄清,h_addr不是struct hostent的字段。定義由預處理器處理,實際編譯看到一個空行,其中#define是。
但是,如果一段代碼被寫爲he.h_addr,則預處理器將對其進行修改並將其替換爲he.h_addr_list[0]。這就是實際的編譯器會看到的。

預處理器宏從未被確定範圍:編譯器本身甚至沒有看到它們 - 它只看到替換的結果,並且預處理器完全忽略(不知道)範圍。

+0

我完全理解您的回覆。例如,爲什麼'h_addr'成爲'struct hostent'的成員,當它只是一個宏? – pap42

+2

'h_addr'不是'struct hostent'的字段。該定義由預處理器處理,實際的編譯器在'#define'處看到空行。但是,如果一段代碼被寫爲'he.h_addr',則預處理器將修改它並將其替換爲'he.h_addr_list [0]'。這就是實際的編譯器會看到的。 – Mat

+0

您的回覆非常好,但我認爲您應該對其進行編輯,使其對未來的讀者更加清晰(可能包括您剛剛發表的評論?)。 – pap42

5

一旦定義,宏標識符保持可見獨立於C範圍規則。其範圍從其定義開始,直到翻譯單元末尾或相應的指令#undef

這裏,結構中的定義只是爲了可讀性;你也可以在你的結構之後定義你的宏,例如:

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] 

它根本不是字段;它允許用戶編寫s.h_addr而不是s.h_addr_list[0]

0

宏定義不作用域所以這個宏內編制的單位,看到這個定義,直到undef h_addr是可見的。