12

以下の構造体の定義に、マクロ定義の行があります ( #define)。その行は正確に何をしますか?array の最初のエントリにエイリアスを作成することは理解しています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 */
};
4

3 に答える 3

23

マクロ定義はまったくスコープされていません。その構造体の外で定義された場合と同じように機能します。

hr.h_addrこれにより、古いコードを変更する必要がなくなり、引き続き使用できます(が であるとhe.h_addr_list[0]仮定します)。hestruct 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 に答える