1

2つのヘッダーファイルがどちらか一方で定義されたデータ構造を必要とする状況があります。つまり、どちらの順序でインクルードしてもコンパイルされません。

ただし、問題のあるデータ構造の1つには、他のヘッダーファイルで宣言されたデータ構造へのポインターしか含まれていないため、技術的には、この時点でデータ構造の大きさを知る必要はないので、そうすべきではありません。文句を言う

私が言っていることの簡単な例を以下に概説します。ライブラリ内のモードの配列は、モードの大きさを知る必要はなく、モードへのポインタの大きさだけを知る必要があると思っていたので、コンパイラは、モードの宣言をまだ見ていない場合でも文句を言うべきではありません。他のヘッダーファイルにあります。

header_1.h

typedef struct
{
    Mode **modes; 
} Library;

header_2.h

typedef struct
{
    int number;
    char *name;
} Mode;
4

3 に答える 3

3

サイズを知る必要はありませんが、宣言を見たに違いありません。前方宣言

typedef struct Mode Mode;

struct Library十分の定義の前に。

于 2012-07-09T13:38:30.750 に答える
2

現在書かれているように、あなたの例はあなたが質問で言及している相互参照を示していません。

コンパイラーは、使用する各タイプについて何かを知らされなければなりません。あなたはheader_1.hただで使うことができます:

typedef struct Mode Mode;

typedef struct
{
    Mode **modes; 
} Library;

それは少なくともそれをコンパイルさせるでしょう。コンパイラは詳細を必要としませんが、それがModes型であることを知る必要があります。

編集:header_2.hこれが機能するように変更する必要があることに 注意してください。それぞれが1回だけ表示されることを確認する必要がありtypedefます。typedefを配置したら、構造体の内容(定義)を1回指定し、構造typedef体の定義からキーワードとtypedef名を省略します。そして、相互参照が管理されることを正確に決定する必要があります。たとえば、とにかくheader_1.h含める必要があります。header_2.h

相互に参照する構造が本当に必要だったケースに遭遇したことを覚えていません(非常に長い時間のプログラミングで、例を忘れてしまうほど長い時間でした)。 私は今、相互に参照し合う構造の事例を覚えています。makeもともとMinix用に書かれたバージョンでした。私はまだそのような要件をやや「病的」(または、必要に応じて「コードの臭い」)であり、可能な限り避けるべきものと見なしています。あなたが本当にそれを管理しなければならないのなら、以下のセクションは私がそれをどのように行うか(そして多かれ少なかれmakeプログラムがそれをどのように行ったか)を説明します。

相互参照構造

本当に2つの相互参照構造がある場合は、2つのヘッダーが1つよりも優れていると考える理由を(再)検討する必要があります。それでも2つのヘッダーが必要な場合は、次のようなイディオムを使用します。

header_1.h

#ifndef HEADER_1_H_INCLUDED
#define HEADER_1_H_INCLUDED

#ifndef TYPEDEF_MODE
#define TYPEDEF_MODE
typedef struct Mode Mode;
#endif
#ifndef TYPEDEF_LIBRARY
#define TYPEDEF_LIBRARY
typedef struct Library Library;
#endif

struct Library
{
    ...
    Mode    **modes;
    ...
};

#endif /* HEADER_1_H_INCLUDED */

header_2.h

#ifndef HEADER_2_H_INCLUDED
#define HEADER_2_H_INCLUDED

#ifndef TYPEDEF_MODE
#define TYPEDEF_MODE
typedef struct Mode Mode;
#endif
#ifndef TYPEDEF_LIBRARY
#define TYPEDEF_LIBRARY
typedef struct Library Library;
#endif

struct Mode
{
    ...
    Library    **liblist;
    ...
};

#endif /* HEADER_2_H_INCLUDED */

繰り返されるtypedef「検出」コードは適切ではありません。私の推定では、単一のヘッダーの方が優れています。header_1.hただし、上記のいずれかの順序で含めることができ、header_2.hコンパイルする必要があります。

于 2012-07-09T13:38:23.350 に答える
0

「Mode」はtypedefを使用して定義された型であり、構造体の名前ではないため、これが発生していると思います。明示的に前方宣言する必要があるか、次のように構造化されたコードを使用してみることができます。

header_1.h

typedef struct
{
    struct _Mode_t **modes; 
} Library;

header_2.h

typedef struct _Mode_t
{
    int number;
    char *name;
} Mode;
于 2012-07-09T13:41:19.357 に答える