12

在下面的结构定义上,有一行带有宏定义(#define)。那条线到底是做什么的?我知道它为数组的第一个条目创建了一个别名h_addr_list,但它对我来说仍然很奇怪。是h_addrstruct 的成员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 */
};
4

3 回答 3

23

宏定义根本没有作用域,如果它是在该结构之外定义的,它将以相同的方式工作。

它允许旧代码继续使用,hr.h_addr而不必更改为he.h_addr_list[0](假设he是 a struct hostent)。

澄清一下,h_addr不是struct hostent. 该定义由预处理器处理,实际的编译器在该处看到一个空行#define
但是如果一段代码写成he.h_addr,预处理器会修改它并替换为he.h_addr_list[0]. 这就是实际的编译器将看到的。

预处理器宏从不限定范围:编译器本身甚至看不到它们 - 它只看到替换的结果,而预处理器完全忽略(不知道)范围。

于 2012-09-03T11:50:22.137 回答
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].

于 2012-09-03T11:49:55.767 回答
0

宏定义没有作用域,因此这个宏在看到这个定义的编译单元中是可见的,直到undef h_addr.

于 2012-09-03T11:50:05.593 回答