2012-09-03 102 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是可见的。