在struct定义中定义宏

时间:2012-09-03 11:47:12

标签: c macros structure

在下面结构的定义中,有一条带有宏定义的行(#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 */
};

3 个答案:

答案 0 :(得分:18)

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

它允许旧代码继续使用hr.h_addr,而不必更改为he.h_addr_list[0](假设hestruct 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