私はこのコードを持っています:
main.h
#ifndef MAINH
#define MAINH
...
#include "my_struct.h"
void some_func(my_structure *x);
...
#endif
そして
my_struct.h
#ifndef UTILSH
#define UTILSH
...
#include "main.h"
...
typedef struct abcd {
int a;
} my_structure;
...
#endif
しかし、コンパイルしようとすると次のようになります:error: unknown type name ‘my_structure’
理由は何ですか?
インクルードの順序付けのため、コンパイラは_typedef struct abcd { int a; } my_structure;
_を見る前にvoid some_func(my_structure *x);
を見る。
おもう。
これを見ていきましょう。
_my_struct.h
_が最初に処理されると仮定すると、次の一連のイベントを取得します。
UTILSH
が定義されていますMAINH
が定義されていますUTILSH
はすでに定義されているため、_my_struct.h
_を再度処理しないため、typedefは処理されませんvoid some_func(my_structure *x);
が処理されます。したがって、前処理後、コンパイラは次の宣言シーケンスを認識します。
_...
void some_func(my_structure *x);
...
typedef struct abcd {...} my_structure;
_
悪いジュジュ。 _my_structure
_内の_main.h
_の前方宣言が必要か、その循環依存関係を解除する必要があります(これは非常に望ましいオプションです)。 _main.h
_に_my_structure.h
_が実際に使用するものはありますか?その場合は、_main.h
_と_my_structure.h
_の両方が含まれる別個のファイルに分解する必要があります。
循環ヘッダーインクルージョンを作成しました。円形の包含は決して何も達成しません。無限です。 #ifndef
インクルードガードは、予測不能なポイントで無限の包含円を壊します(最初に.c
ファイルに含まれるヘッダーによって異なります)。これがあなたのケースで起こったことです。基本的に、循環インクルードは、最初にmain.h
、2番目にmy_struct.h
を含むように「解決」されました。これがmain.h
がmy_struct
タイプについて何も知らない理由です。
繰り返しますが、循環包含は何も達成しません。円形の包含を取り除きます。ヘッダー構造を階層的に設計します。低レベルヘッダーは高レベルヘッダーに含まれますが、その逆はできません。あなたの場合、my_struct.h
はおそらく低レベルのヘッダーです。つまり、main.h
へのmy_struct.h
の挿入を停止する必要があります。 my_struct.h
がmain.h
を必要としないように、ヘッダーを再設計します。
エラーメッセージは、main.h
が定義されている前に、my_struct.h
に含まれているときにmy_structure
から送信されます。 main.h
とmy_struct.h
が相互に含まれるため、インクルードパスを再検討する必要があります。
おそらくmain.h
ファイルにはmy_struct.h
のみを含め、my_struct.h
には何も含めないようにする必要があります。基本的に、Cコンパイラに無限の共包含ループを作成するよう指示しています。