在下面结构的定义中,有一条带有宏定义的行(#define
)。那条线究竟做了什么?我理解它为数组h_addr_list
的第一个条目设置别名,但它对我来说仍然看起来很奇怪。 h_addr
是结构hostent
的成员吗?这个定义只在结构范围内吗?
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 */
};
答案 0 :(得分:18)
宏定义根本没有作用域,如果它在该结构之外定义,它将以相同的方式工作。
它允许旧代码继续使用hr.h_addr
,而不必更改为he.h_addr_list[0]
(假设he
为struct hostent
)。
为了澄清,h_addr
不是struct hostent
的字段。该定义由预处理器处理,实际的编译器看到#define
所在的空行。
但如果一段代码写为he.h_addr
,预处理器将对其进行修改并将其替换为he.h_addr_list[0]
。这就是实际编译器将看到的内容。
预处理器宏从不作用域:编译器本身甚至看不到它们 - 它只看到替换的结果,并且预处理器完全忽略(不知道)作用域。
答案 1 :(得分:6)
一旦定义,宏标识符将独立于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]
。
答案 2 :(得分:0)
宏定义没有作用域,因此这个宏在看到此定义的编译单元中可见,直到undef h_addr
。