Определение макроса внутри определения структуры

В определении структуры ниже существует строка с определением макроса (#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 */
};

Ответ 1

Определение макроса не ограничено вообще, оно будет работать одинаково, если оно определено вне этой структуры.

Это позволяет старым кодам продолжать использовать hr.h_addr вместо того, чтобы быть замененным на he.h_addr_list[0] (предполагается, что he - это struct hostent).

Чтобы уточнить, h_addr не является полем struct hostent. Это определение обрабатывается препроцессором, фактический компилятор видит пустую строку, где находится #define.
Но если кусок кода написан как he.h_addr, препроцессор изменит его и заменит на he.h_addr_list[0]. Именно это увидит настоящий компилятор.

Макросы предварительного процессора никогда не облагаются областью: сам компилятор даже не видит их - он видит только результат подстановок, и предварительный процессор полностью игнорирует (не знает).

Ответ 2

После определения идентификатор макроса остается видимым независимо от правил определения 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].

Ответ 3

Определения макросов не ограничены, поэтому этот макрос отображается внутри единиц компиляции, которые видят это определение, и до undef h_addr.